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

如何在TypeScript中对string类型与字面量类型做类型分支判断?

问题原因

报错本质是 TypeScript 无法对当前的联合类型 T 完成正确的类型窄化:联合类型第一个分支的 type 类型是通用 string,字面量 "foo" 属于 string 的子集,所以当你判断 foo.type === "foo" 时,TypeScript 认为两个分支的类型都有可能命中,无法排除掉没有 bar 属性的第一个分支,因此抛出属性不存在的错误。

解决方案
  • 方案1:调整联合类型的定义,让两个分支的 type 字段互斥
    把第一个分支的 type 类型改为排除 "foo" 的字符串类型,这样 TypeScript 就可以通过 type 字段的判断正确窄化类型:
type T =
  | {
      type: Exclude<string, "foo">;
    }
  | {
      type: "foo";
      bar: number;
    };

const func = (foo: T) => {
  if (foo.type === "foo") {
    // 此时可以正确识别foo的类型为第二个分支,bar属性存在
    return foo.bar
  }
}
  • 方案2:自定义类型守卫实现类型窄化
    如果不能修改原有的 T 类型定义,可以手写类型守卫函数,主动告诉 TypeScript 判定逻辑对应的类型规则:
type T =
  | {
      type: string;
    }
  | {
      type: "foo";
      bar: number;
    };

// 自定义类型守卫
const isFooType = (val: T): val is Extract<T, {type: "foo"}> => {
  return val.type === "foo"
}

const func = (foo: T) => {
  if (isFooType(foo)) {
    return foo.bar
  }
}
  • 方案3:使用类型断言(兜底方案,不推荐)
    如果你确定当前分支下 foo 一定存在 bar 属性,可以直接用类型断言跳过 TypeScript 的检查,但是这种方式会丢失类型校验能力,只有在你确认逻辑没问题的情况下使用:
const func = (foo: T) => {
  if (foo.type === "foo") {
    return (foo as Extract<T, {type: "foo"}>).bar
  }
}

内容的提问来源于stack exchange,提问作者islandryu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 08:36:00