TypeScript中string[]数组索引访问元素被推断为undefined原因
问题描述
现有一个名为checkMultipleImgs的异步函数,声明返回值为字符串填充的数组(string[]类型),实现代码如下:
const checkMultipleImgs = async (fileName: string): Promise<string[]> => { const { data, error } = await supabase.storage.from('fitting').list('', { offset: 0, sortBy: { column: 'name', order: 'asc' }, search: fileName, }); return data ? data.map((item) => item.name) : []; };
变量newUrls为调用checkMultipleImgs函数得到的返回值,预期类型为string[],相关业务逻辑代码如下:
const newUrls = await checkMultipleImgs(fileName); if (newUrls && newUrls.length > 0) { for (let i = 0; i < newUrls.length; i++) { const newFileName = newUrls[i]; const url = await getImgUrl(newFileName); if (url) { urls.push(url); } } }
编写代码时触发TypeScript类型校验报错,提示newUrls[i]的类型为string | undefined,即使明确标注函数返回string[]类型,通过索引访问元素时仍然被推断包含undefined类型,报错参考截图:
报错原因
该报错是TypeScript的noUncheckedIndexedAccess编译规则生效导致的:
当tsconfig中开启该选项后,TypeScript不会默认信任数组索引访问的返回值一定存在——因为静态类型检查无法覆盖所有运行时场景(比如数组被意外修改、索引计算偏差导致越界等),因此会自动给索引访问的返回值追加undefined类型,即使数组本身已经明确标注为string[]。
解决方案
可根据项目的类型严格度要求,选择以下任意一种方案修复:
- 方案1:关闭
noUncheckedIndexedAccess配置(不推荐,会丢失该规则带来的越界访问安全防护),在tsconfig.json中将该选项设置为false即可。 - 方案2:添加非空断言,适合100%确定索引访问值一定存在的场景,在访问的元素后加
!告诉TS跳过该值的undefined检查:const newFileName = newUrls[i]!; - 方案3:添加类型收窄判断,符合严格类型规范,访问后判断值是否存在,不存在则跳过后续逻辑:
for (let i = 0; i < newUrls.length; i++) { const newFileName = newUrls[i]; if (!newFileName) continue; const url = await getImgUrl(newFileName); if (url) { urls.push(url); } } - 方案4(推荐):改用
for...of循环遍历数组,TypeScript可以正确推导遍历出的元素类型,不会自动追加undefined,代码也更简洁:const newUrls = await checkMultipleImgs(fileName); if (newUrls?.length > 0) { for (const newFileName of newUrls) { const url = await getImgUrl(newFileName); if (url) { urls.push(url); } } }
内容的提问来源于stack exchange,提问作者jooyeon yi
相关产品推荐
相关产品推荐

