Các cách TypeScript thu hẹp một kiểu bên trong một nhánh, nhóm theo kỹ thuật: guard có sẵn, predicate tự viết, hàm assertion, discriminated union, luồng so sánh bằng và truthiness, cùng thu hẹp qua bí danh và hoãn lại. Mỗi dòng ghép kỹ thuật với một ví dụ một dòng.
Thu hẹp kiểu là cách TypeScript biến một kiểu rộng thành kiểu hẹp hơn bên trong một nhánh code, để nó chứng minh việc truy cập thuộc tính là an toàn. Mọi phép kiểm tra (typeof, in, predicate, discriminator) đều nói với trình biên dịch: từ đây trở đi, giá trị cụ thể hơn. Các kỹ thuật dưới đây là bộ dùng thực tế.
Bảng tham chiếu · 23 mục
Thu hẹp kiểu trong TypeScriptExplained
23 of 23 rows
Guard có sẵn
Thu hẹp kiểu nguyên thủy: string, number, boolean và hơn thế nữa.
if (typeof x === 'string') x.toUpperCase()
Thu hẹp thành một instance của lớp hoặc thứ có thể construct.
if (e instanceof Error) e.message
Thu hẹp bằng cách kiểm tra một thuộc tính tồn tại trên giá trị.
if ('id' in obj) obj.id
Thu hẹp mọi giá trị thành mảng; thu hẹp union thành thành viên mảng của nó.
if (Array.isArray(x)) x.map(f)
Guard tự viết
Hàm predicate mà giá trị trả về thu hẹp đối số.
function isUser(x): x is User { return !!x.id }
Một predicate có thể thu hẹp thành union của nhiều kiểu, không chỉ một kiểu.
function isKey(x): x is string | number
Predicate kiểu giao giữ nguyên kiểu đầu vào và thêm trường vào nó.
function hasId(x): x is x & { id: string }
Hàm assertion ném lỗi trừ khi x là kiểu đó.
function assertUser(x): asserts x is User
Discriminated union
Thu hẹp union qua một trường literal chung, bằng switch hoặc if.
type E = { kind: 'a'; a: number } | { kind: 'b'; b: string }
Mỗi case thu hẹp về một thành viên của union.
switch (u.kind) { case 'a': u.a }
Thu hẹp union không có tag khi một thuộc tính chỉ tồn tại trên một thành viên.
if ('b' in u) u.b
Mỗi case là một điều kiện; case khớp sẽ thu hẹp giá trị.
switch (true) { case typeof x === 'string': }
Case default gán vào never, chứng minh switch đã đủ mọi trường hợp.
default: { const x: never = u }
So sánh bằng & luồng chạy
Loại bỏ null và undefined sau một phép so sánh bằng.
if (x === null) return; x.toFixed()
Loại bỏ các giá trị falsy (0, '', null, undefined, NaN).
if (!x) return; // x is defined here
Một thuộc tính chuỗi truthy chứng minh giá trị gốc tồn tại.
if (user?.active) user.name
Non-null assertion loại bỏ null và undefined mà không cần kiểm tra.
x!.toFixed(2)
Definite assignment: khai báo rằng x được gán trước khi đọc.
let name!: string; init()
Việc thu hẹp có hiệu lực trong nhánh và sau các return sớm.
if (!arr) return; arr.map(...)
Bí danh & hoãn lại
Một const boolean giữ phép kiểm tra sẽ thu hẹp ở bất cứ đâu nó được xét.
const isStr = typeof x === 'string'; if (isStr) …
Một biến const giữ nguyên việc thu hẹp bên trong closure bắt nó.
const s = get(); if (s) use(() => s.length)
Từ TS 5.4, let hoặc tham số giữ việc thu hẹp trong closure sau lần gán cuối.
let n: string | null = get(); if (n) use(() => n.length)
unknown không thể dùng được cho đến khi một guard thu hẹp nó về kiểu thật.