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

TypeScript扩展类型时如何避免未定义错误?

TypeScript扩展类型时如何避免未定义错误?

哥们,我太懂你这种憋屈的感觉了——明明已经加了属性存在性检查,TypeScript还是死咬着“Property 'defaultItems' does not exist on type 'BaseProps'”报错,就像没看到你的检查一样。我来给你捋清楚问题出在哪,再给你几个正经的解决办法。

为什么你的检查没生效?

你用StrictUnion把Props变成了互斥联合类型,这点没问题,但TypeScript的类型守卫有个局限:它没办法自动把嵌套属性的检查,反向关联到外层的联合分支上。

举个例子,当你写if (defaultData.defaultItems)时,TS首先会纠结:defaultData可能是BaseDefaultData,而这个类型根本没有defaultItems属性,所以这个访问本身在TS眼里就是“非法”的,直接提前报错了,根本等不到运行时的检查生效。就算你用了可选链defaultData.defaultItems?.results,TS还是会因为BaseDefaultData没有defaultItems而报错——它没办法从可选链的使用里推断出“当前defaultData应该是ExtendedDefaultData”。

正确的解决办法

办法1:给整个Props做类型守卫

写一个类型谓词函数,直接判断当前的props是不是ExtendedProps,这样TS就能明确知道分支里的类型:

// 定义类型谓词,告诉TS这个函数能判断props的类型
function isExtendedProps(props: Props): props is ExtendedProps {
  // 这里需要临时断言一下,因为BaseDefaultData没有defaultItems,TS会阻止直接访问
  return !!(props.defaultData as ExtendedDefaultData).defaultItems;
}

// 现在用这个守卫包裹代码,TS就不会报错了
if (isExtendedProps(props)) {
  props.defaultData.defaultItems.function(doSomething);
}

// 可选链的场景也可以用三元表达式替代
const results = isExtendedProps(props) ? props.defaultData.defaultItems.results : [];

办法2:针对defaultData单独做类型守卫

如果不想针对整个Props做判断,也可以聚焦于defaultData本身,判断它是不是ExtendedDefaultData:

// 判断defaultData是否包含defaultItems属性
function hasDefaultItems(data: BaseDefaultData | ExtendedDefaultData): data is ExtendedDefaultData {
  return 'defaultItems' in data;
}

// 使用示例
const { defaultData } = props;

// 处理results的场景
const results = hasDefaultItems(defaultData) ? defaultData.defaultItems.results : [];

// 调用函数的场景
if (hasDefaultItems(defaultData)) {
  defaultData.defaultItems.function(doSomething);
}

关于你用defaultData['defaultItems']的问题

这种写法确实能绕过TS的检查,但本质是“欺骗”TS,相当于放弃了类型安全——万一哪天你把defaultItems拼写成defaultItem,TS根本不会提醒你,等到运行时才会出问题,所以非常不推荐这么做。

备注:内容来源于stack exchange,提问作者Alyona

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.20 09:48:00