TypeScript中infer推导异常:为何get("bb")类型为true而非false?
问题:为何变量c的类型是true而非false?
相关代码:
type FromProps<T> = T extends AA<infer E> ? true : false; class AA<E> {} class CC {} class BB { aa: AA<string> = new AA bb: CC = new CC } function get<K extends keyof BB>(a: K): FromProps<BB[K]> { return null as unknown as FromProps<BB[K]> } let c = get("bb"); // 类型被推断为true,预期是false
原因解析
这是因为TypeScript采用结构类型系统:判断类型兼容性时只看结构是否一致,不看类型名称。
你的代码中AA<E>和CC都是空类,它们的实例结构完全相同(没有任何属性或方法),因此TypeScript认为CC是AA<E>的子类型。当T为CC时,条件类型T extends AA<infer E>会判定为true,最终FromProps<CC>的结果就是true。
修复方案
如果要让AA和CC成为名义上不同的类型(即仅靠名称区分),可以给它们添加一个私有标识成员,破坏结构一致性:
class AA<E> { private __aaTag: void } // 添加私有成员 class CC { private __ccTag: void } // 添加私有成员
此时CC和AA<E>的结构不再兼容,FromProps<CC>会正确返回false,调用get("bb")时变量c的类型就会是false。
内容的提问来源于stack exchange,提问作者jerry
相关产品推荐
相关产品推荐

