TypeScript未识别动态对象键取值可能为undefined的解决方法
原因说明
TypeScript 的 strict: true 配置不会自动对索引签名的访问结果添加 undefined 类型。默认规则下,{ [key: string]: T } 类型的对象被判定为「任意字符串键都一定存在对应T类型的值」,哪怕对象初始值是空对象,也不会触发可能为undefined的类型报错。
你没拿到预期报错的核心原因是:针对动态索引访问的严格检查是独立的编译选项,不在strict套件的默认开启范围内。
实现严格检查的两种方式
1. 全局开启索引访问严格检查
在tsconfig.json中开启noUncheckedIndexedAccess选项即可,这个选项是TS专门为动态键访问场景设计的严格校验规则:
{ "compilerOptions": { "strict": true, "noUncheckedIndexedAccess": true } }
开启后,所有通过字符串索引、数字索引、数组下标访问得到的值,类型会自动被推导为原类型 | undefined,你给出的示例代码会直接抛出「对象可能为 'undefined'」的类型错误,强制要求你在调用方法前做存在性校验。
这个选项从TypeScript 4.1版本开始稳定支持,和你当前使用的v4.7.3版本完全兼容。
2. 单对象手动标注类型
如果你不想全局开启该规则,只需要对特定的hashmap对象做严格校验,可以直接在定义索引签名时,手动给值类型联合undefined:
// 明确标注键对应的值可能不存在 const promiseCache: { [key: string]: Promise<void> | undefined } = {}; // 以下代码会直接触发类型报错 promiseCache['4c8e17ce-9ca5-457a-925e-a8c36fe90508'].then(() => { console.log('then!'); }); // 符合类型要求的写法:先判空再使用 const targetPromise = promiseCache['4c8e17ce-9ca5-457a-925e-a8c36fe90508']; if (targetPromise) { targetPromise.then(() => { console.log('then!'); }); }
补充说明:如果项目里大量使用这种动态键缓存对象的模式,优先推荐开启
noUncheckedIndexedAccess,可以避免手动给每个索引签名加undefined的重复工作,也能覆盖数组下标访问的边界检查场景。
内容的提问来源于stack exchange,提问作者caleb531
相关产品推荐
相关产品推荐

