TypeScript自定义类型守卫在if语句中不生效问题咨询
问题原因及解决方案
你的类型守卫不生效的核心原因是TypeScript的结构类型系统:只要两个类型的结构完全一致,就会被视为等价类型。你定义的A和B接口结构完全相同(都只有type: FooType字段),所以在TypeScript看来,A和B是同一个类型,类型守卫自然无法对变量类型进行收窄。
解决方法
你需要让A和B的结构产生明确差异,让TypeScript能区分它们,这里提供两种常用方案:
方案1:给B添加独有属性
给B接口增加一个仅属于它的属性,让两个接口结构不同:
function test(foo: A) { if(isB(foo)) { console.log('foo', foo); // 此时foo会被正确识别为B类型 } } function isB(foo: A): foo is B { return foo.type === FooType.B } interface A { type: FooType } interface B extends A { // 新增B独有的属性 bSpecificProp: string } enum FooType { A, B }
方案2:用枚举字面量约束type字段
直接把接口的type字段约束为枚举的具体值,让A和B的type类型明确区分:
function test(foo: A | B) { // 参数类型改为A|B,因为现在A和B的type是不同字面量 if(isB(foo)) { console.log('foo', foo); // foo会被识别为B类型 } } function isB(foo: A | B): foo is B { return foo.type === FooType.B } interface A { type: FooType.A } interface B { type: FooType.B } enum FooType { A, B }
内容的提问来源于stack exchange,提问作者Shiuyin
相关产品推荐
相关产品推荐

