为何TypeScript联合类型收窄必须使用"in"操作符?
为什么TypeScript联合类型收窄不能直接检查属性,必须用
in操作符? 先看你提到的错误示例:
type Obj1 = { message: string } type Obj2 = { text: string } const getText = (obj: Obj1 | Obj2): string => { if (obj.message) { // <- 'message' does not exist on type 'Obj1 | Obj2' return obj.message } return obj.text }
正确的写法需要使用in操作符:
const getText2 = (obj: Obj1 | Obj2): string => { if ("message" in obj) { return obj.message } return obj.text }
原因主要有两点:
- TypeScript的类型检查规则:联合类型中只要有一个成员不包含某个属性,直接访问该属性就会触发报错。上面的例子里
Obj2没有message,所以obj.message在类型检查阶段就不被允许,TypeScript不会执行“先判断属性存在再收窄类型”的逻辑。 in是官方认可的类型保护:in操作符是TypeScript专门用来做类型收窄的语法之一,当你用"message" in obj时,TypeScript会明确识别出:条件成立时obj必然是包含message的Obj1类型,此时自动完成类型收窄,访问obj.message就合法了。
另外还有一个潜在逻辑问题:就算Obj1的message是空字符串,if (obj.message)会被判定为false,代码会走到返回obj.text的分支,但此时obj其实是Obj1类型,根本没有text属性,这会导致运行时错误,TypeScript提前拦截了这种风险。
内容的提问来源于stack exchange,提问作者Xen_mar
相关产品推荐
相关产品推荐

