You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 02:48:14