收窄是 TypeScript 根据运行时检查将宽泛类型(如联合类型)在代码分支内精化为更具体类型的方式。编译器跟踪控制流并相应地更新类型。
ts
function process(x: string | number) {
if (typeof x === "string") {
x.toUpperCase(); // ✅ here x is narrowed to string
} else {
x.toFixed(2);
}
}
收窄是 TypeScript 根据运行时检查将宽泛类型(如联合类型)在代码分支内精化为更具体类型的方式。编译器跟踪控制流并相应地更新类型。
function process(x: string | number) {
if (typeof x === "string") {
x.toUpperCase(); // ✅ here x is narrowed to string
} else {
x.toFixed(2);
}
}
typeof x === "string" // typeof guard — for primitives
x instanceof Date // instanceof — for classes
"role" in obj // in operator — property existence
Array.isArray(x) // built-in guards
if (x) { ... } // truthiness narrows out null/undefined/0/""
if (x === null) { ... } // equality narrowing
type Shape =
| { kind: "circle"; r: number }
| { kind: "square"; side: number };
function area(s: Shape) {
switch (s.kind) { // the discriminant
case "circle": return Math.PI * s.r ** 2; // s is the circle variant
case "square": return s.side ** 2; // s is the square variant
}
}
检查共享的字面量字段 (kind) 确切地告诉编译器你拥有哪个变体,从而解锁该变体的属性。
function isUser(x: unknown): x is User { return !!x && typeof (x as any).name === "string"; }
收窄使联合类型可用 — 它允许你在证明类型后,仅安全地访问类型特定的成员,将运行时检查转化为编译时保证。
这是处理 string | number、T | null 和标记状态的日常机制。