TS2339解构报属性不存在 如何不全量定义联合类型成员修复
问题描述
编写函数时根据传入的Types联合类型参数返回对应辅助方法,未匹配到对应方法时返回默认辅助方法,TypeScript抛出TS(2339)报错,提示类型上不存在对应属性。要求不逐一声明Types联合类型的所有成员,也不使用if / switch条件分支语句,需要修复该类型错误。
复现代码如下:
type Types = 'foo' | 'bar' | 'baz'; const fooHelper = () => console.log('fooHelper'); const getHelper = (t: Types) => { const defaultHelper = () => console.log(t); // Property 'bar' does not exist on type '{ foo: () => void; }'.ts(2339) // Property 'baz' does not exist on type '{ foo: () => void; }'.ts(2339) const { [t]: helper = defaultHelper } = { foo: fooHelper, }; return helper; };
修复方案
报错核心原因是TS静态校验时,判定解构用的对象字面量仅包含foo属性,无法覆盖Types联合类型的所有可能取值,因此认为用联合类型变量做动态索引访问属于非法操作。
只需要给存放辅助方法的对象显式标注Partial<Record<Types, () => void>>类型,告知TS该对象允许仅包含Types下的部分成员,缺失成员会走解构默认值逻辑即可,无需修改业务逻辑,也不需要补全所有联合类型成员、编写条件分支。
修复后代码:
type Types = 'foo' | 'bar' | 'baz'; const fooHelper = () => console.log('fooHelper'); const getHelper = (t: Types) => { const defaultHelper = () => console.log(t); const helpers: Partial<Record<Types, () => void>> = { foo: fooHelper, }; const { [t]: helper = defaultHelper } = helpers; return helper; };
类型说明
Record<Types, () => void>用于定义键为所有Types联合成员、值为无返回值函数的对象类型- 外层包裹
Partial会将对象所有属性转为可选,允许仅定义部分键值对,满足无需逐一声明所有联合成员的要求 - 解构时设置的默认值
= defaultHelper会在对应键不存在、或键值为undefined时自动生效,完全替代if/switch分支判断的能力
内容的提问来源于stack exchange,提问作者Daniel Ishitani
相关产品推荐
相关产品推荐

