变量能否作为TypeScript类型守卫使用?
普通布尔变量能否充当TypeScript的类型守卫?
在TypeScript中存在这样的场景:直接在if条件中使用typeof判断联合类型变量时,TypeScript可以正确缩小变量的类型范围;但将判断结果存入普通布尔变量后,使用该变量进行if判断却无法实现类型缩小。
代码示例:
type Union = string | {prop: string}; function test(u: Union) { if (typeof u === "string") { u; // ^? (parameter) u: string } if (typeof u === "object") { u; // ^?(parameter) u: { prop: string } } let check = typeof u === "object"; // ^?let check: boolean if (check) { u.prop; // ^?(parameter) u: Union } }
答案:普通布尔变量无法直接充当类型守卫
原因如下:
- TypeScript的类型窄化依赖对条件表达式的静态上下文分析。当你直接在
if条件中写typeof u === "object"时,TypeScript能识别这是针对变量u的类型检查,从而关联并执行u的类型缩小逻辑。 - 普通布尔变量仅存储
true/false值,无法携带“该结果基于原变量u的类型判断得出”的上下文信息。TypeScript无法追踪这个变量与u的关联,自然无法通过它的真假推断u的类型。
如果想用变量实现类似类型守卫的效果,可以自定义带类型谓词的函数:
type Union = string | {prop: string}; // 自定义类型守卫函数,返回值使用类型谓词 function isUnionObject(u: Union): u is {prop: string} { return typeof u === "object" && u !== null; } function test(u: Union) { if (isUnionObject(u)) { u.prop; // 此时u的类型被正确缩小为{prop: string} } }
类型谓词u is {prop: string}会明确告诉TypeScript:当函数返回true时,参数u的类型必然是{prop: string},这样就能实现基于函数返回值的类型窄化。
内容的提问来源于stack exchange,提问作者Nico Richter
相关产品推荐
相关产品推荐

