类型收窄:typeof、instanceof 与可辨识联合
使用类型保护,在运行时通过 typeof、instanceof 和可辨识联合模式收窄联合类型。
类型收窄:typeof、instanceof 与可辨识联合 是 CoddyKit 上的免费 Frontend Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Frontend Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Frontend Academy 课程共包含 4 节课。
什么是类型收窄
TypeScript 起初使用宽泛类型(例如 string | number)。类型收窄是指在条件代码块中,将类型细化为更具体类型的过程。TypeScript 会自动跟踪类型收窄。
typeof 类型收窄
typeof 运算符可以收窄原始类型。在 if 代码块中,TypeScript 知道确切的类型。
function format(value: string | number | boolean): string {
if (typeof value === 'string') {
return value.toUpperCase(); // string here
}
if (typeof value === 'number') {
return value.toFixed(2); // number here
}
return String(value); // boolean here
}instanceof 类型收窄
instanceof 可以收窄类实例的类型。TypeScript 能在代码块中知道具体的类。
function processError(err: unknown) {
if (err instanceof Error) {
console.error(err.message); // Error methods available
} else if (err instanceof Response) {
console.error('HTTP error:', err.status);
} else {
console.error('Unknown:', err);
}
}真值类型收窄
TypeScript 会在真值检查中排除 null 和 undefined。
function printLength(value: string | null | undefined) {
if (value) {
console.log(value.length); // string here (null/undefined filtered)
}
}相等性类型收窄
严格相等性检查会将类型收窄为字面量类型。这对判别联合类型和字符串枚举很有用。
function handle(action: 'submit' | 'cancel' | 'reset') {
if (action === 'submit') {
// action is exactly 'submit'
doSubmit();
}
}in 运算符类型收窄
in 运算符通过检查对象存在哪些属性,来收窄对象联合类型。
interface Cat { meow(): void; }
interface Dog { bark(): void; }
function speak(animal: Cat | Dog) {
if ('meow' in animal) {
animal.meow(); // Cat
} else {
animal.bark(); // Dog
}
}判别联合类型 — 基于标签的类型收窄
判别联合类型具有一个共享的字面量类型属性(即判别属性)。TypeScript 会根据该属性,在 switch 或 if 中收窄联合类型。
type LoadingState = { status: 'loading' };
type SuccessState = { status: 'success'; data: User[] };
type ErrorState = { status: 'error'; message: string };
type State = LoadingState | SuccessState | ErrorState;
function render(state: State) {
switch (state.status) {
case 'loading': return '<Spinner />';
case 'success': return renderUsers(state.data); // state.data available
case 'error': return renderError(state.message);
}
}类型谓词 — 自定义类型守卫
类型谓词函数会为调用方收窄类型。请将 param is Type 用作返回类型。
function isUser(value: unknown): value is User {
return (
typeof value === 'object' &&
value !== null &&
'name' in value &&
typeof (value as User).name === 'string'
);
}
const data: unknown = await fetchJson('/api/me');
if (isUser(data)) {
console.log(data.name); // typed as User
}断言函数
如果条件不成立,断言函数会抛出错误;调用完成后,类型就会被收窄。
function assertIsString(val: unknown): asserts val is string {
if (typeof val !== 'string') throw new Error('Expected string');
}
const val: unknown = getInput();
assertIsString(val);
console.log(val.toUpperCase()); // val is string here完备性检查
当针对判别联合类型的 switch 在 default 分支中留下 never 类型时,TypeScript 会确保所有情况都已处理。请添加一个将值赋给 never 的 default;这样如果新增变体,编译时就会报错。
function render(state: State): string {
switch (state.status) {
case 'loading': return '...';
case 'success': return state.data.length.toString();
case 'error': return state.message;
default:
const _exhaustive: never = state;
throw new Error('Unhandled state: ' + _exhaustive);
}
}使用 Array.isArray 进行类型收窄
Array.isArray() 会将值收窄为数组类型。
function processInput(input: string | string[]) {
if (Array.isArray(input)) {
return input.join(', '); // string[]
}
return input.toUpperCase(); // string
}快速检查
哪种类型收窄技术使用共享的字面量属性来区分联合类型的不同变体?
回顾:TypeScript 类型收窄
使用 typeof 处理原始类型。使用 instanceof 处理类。使用 in 运算符处理对象形状。真值检查会筛除 null/undefined。带有共享字面量属性的判别联合类型可以实现完备的 switch 语句。使用自定义类型谓词(is)进行复杂的运行时检查。在 default 中使用 never 进行完备性检查。
常见问题解答
「类型收窄:typeof、instanceof 与可辨识联合」课时是免费的吗?
是的 — 「类型收窄:typeof、instanceof 与可辨识联合」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Frontend Academy 课程的其余内容,请升级到 CoddyKit PRO。 Frontend Academy 课程共包含 4 节课。
「类型收窄:typeof、instanceof 与可辨识联合」这节课中我会学到什么?
使用类型保护,在运行时通过 typeof、instanceof 和可辨识联合模式收窄联合类型。 你通过在浏览器中直接运行的动手代码来练习 Frontend Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Frontend Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Frontend Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「类型收窄:typeof、instanceof 与可辨识联合」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Frontend Academy 课中编写并运行代码吗?
能。每节 Frontend Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 泛型:T、extends 与约束
- 工具类型:Partial、Required、Pick 与 Omit
- 映射类型与条件类型
- 类型收窄:typeof、instanceof 与可辨识联合