راههایی که تایپاسکریپت یک نوع را داخل یک شاخه محدود میکند، دستهبندیشده بر پایهٔ تکنیک: گاردهای داخلی، predicateهای سفارشی، توابع assertion، یونینهای متمایز، جریان برابری و درستی، و محدودسازی مستعار و بهتعویقافتاده. هر سطر تکنیک را با یک نمونهٔ یکخطی جفت میکند.
محدودسازی یعنی تایپاسکریپت چگونه یک نوع پهن را داخل یک شاخهٔ کد به نوعی محدودتر تبدیل میکند تا بتواند اثبات کند دسترسی به یک ویژگی امن است. هر بررسی (typeof، in، یک predicate، یک discriminator) به کامپایلر میگوید: از اینجا به بعد، مقدار مشخصتر است. تکنیکهای زیر مجموعهٔ کاریِ اصلی هستند.
جدول مرجع · 23 مورد
محدودسازی نوع در تایپاسکریپتExplained
23 of 23 rows
گاردهای داخلی
نوعهای اولیه را محدود میکند: string، number، boolean و موارد دیگر.
if (typeof x === 'string') x.toUpperCase()
به نمونهٔ یک کلاس یا سازنده محدود میکند.
if (e instanceof Error) e.message
با بررسی وجود یک ویژگی روی مقدار، محدود میکند.
if ('id' in obj) obj.id
هر مقداری را به آرایه محدود میکند؛ یونین را به عضو آرایهایاش محدود میکند.
if (Array.isArray(x)) x.map(f)
گاردهای سفارشی
یک تابع predicate که مقدار بازگشتیاش آرگومان را محدود میکند.
function isUser(x): x is User { return !!x.id }
یک predicate میتواند به یونینی از نوعها محدود کند، نه فقط به یک نوع.
function isKey(x): x is string | number
predicate تقاطعی نوع ورودی را نگه میدارد و فیلدهایی به آن اضافه میکند.
function hasId(x): x is x & { id: string }
تابع assertion که اگر x از آن نوع نباشد، خطا پرتاب میکند.
function assertUser(x): asserts x is User
یونینهای متمایز
یونین را با یک فیلد literal مشترک، از طریق switch یا if محدود میکند.
type E = { kind: 'a'; a: number } | { kind: 'b'; b: string }
هر case به یکی از اعضای یونین محدود میکند.
switch (u.kind) { case 'a': u.a }
یونین بدون برچسب را وقتی محدود میکند که ویژگی فقط روی یک عضو وجود داشته باشد.
if ('b' in u) u.b
هر case یک شرط است؛ case منطبق، مقدار را محدود میکند.
switch (true) { case typeof x === 'string': }
case پیشفرض به never تخصیص میدهد و اثبات میکند switch کامل است.
default: { const x: never = u }
برابری و جریان
بعد از بررسی برابری، null و undefined را حذف میکند.
if (x === null) return; x.toFixed()
مقدارهای falsy را حذف میکند (0، ''، null، undefined، NaN).
if (!x) return; // x is defined here
ویژگی زنجیرهایِ درست، وجود مقدار پایه را اثبات میکند.
if (user?.active) user.name
اثبات non-null بدون بررسی، null و undefined را حذف میکند.
x!.toFixed(2)
تخصیص قطعی: اعلام میکند که x قبل از خواندهشدن مقدار میگیرد.
let name!: string; init()
محدودسازی داخل شاخه و بعد از returnهای زودهنگام اعمال میشود.
if (!arr) return; arr.map(...)
مستعار و بهتعویقافتاده
یک boolean از نوع const که شرطی را نگه میدارد، هر جا آزموده شود محدود میکند.
const isStr = typeof x === 'string'; if (isStr) …
متغیر const محدودسازیاش را داخل closureهایی که آن را میگیرند حفظ میکند.
const s = get(); if (s) use(() => s.length)
از TS 5.4 به بعد، let یا پارامتر بعد از آخرین تخصیصش، محدودسازی را در closureها نگه میدارد.
let n: string | null = get(); if (n) use(() => n.length)
تا وقتی یک guard آن را به یک نوع واقعی محدود نکند، unknown قابل استفاده نیست.