TypeScript类型谓词转译后is语句擦除,类型检查如何实现?
TypeScript类型谓词的类型检查逻辑
你的疑问核心在于混淆了TypeScript的编译时类型检查和运行时代码执行,这是两个完全独立的阶段:
1. TypeScript的类型检查只发生在编译阶段
类型谓词(比如order is InternetOrder)本质是给TypeScript编译器的“提示”,告诉它:当这个函数返回true时,传入的参数一定是指定的类型。
编译器会基于这个提示做类型收窄:
function handleOrder(order: PossibleOrders) { if (isAnInternetOrder(order)) { // 编译时TS直接认定这里的order是InternetOrder类型 console.log(order.email); // 不会报类型错误 } else if (isATelephoneOrder(order)) { console.log(order.callerNumber); // 同理,这里被认定为TelephoneOrder } }
这一步的类型验证在代码转译成JavaScript之前就已经完成了,转译后的JS代码不会保留任何类型相关的信息——因为JS本身是动态类型语言,不需要这些。
2. 转译后的JS只保留运行时的判断逻辑
你看到的JS代码里的return order && "email" in order,是运行时用来区分订单类型的实际逻辑,和TypeScript的类型检查无关。它的作用是在代码运行时,真正判断当前订单属于哪种类型,从而执行对应的分支逻辑。
简单说:
- TS负责在编译时帮你“把关”,确保你不会写出访问不存在属性的代码;
- 转译后的JS负责在运行时执行实际的类型判断和业务逻辑。
3. 没有类型谓词会怎样?
如果去掉order is InternetOrder这个类型谓词,TS编译器就无法识别函数返回值和参数类型的关联,这时候在if分支里访问order.email会直接报类型错误——因为编译器不确定此时的order是否包含email属性。类型谓词的作用就是让编译器认可你的运行时判断逻辑,从而完成类型收窄。
内容的提问来源于stack exchange,提问作者Kabocha Porter
相关产品推荐
相关产品推荐

