← 返回题目列表

noUncheckedIndexedAccess 解决了什么类型安全问题?

中等 第 31 / 32 题 更新于 2026/07/29
TypeScripttsconfig类型安全

简化版

noUncheckedIndexedAccess 会让通过索引访问数组或对象时,把结果类型自动加上 undefined,提醒你这个 key 或下标可能不存在。

它能发现很多越界访问、字典缺 key 的问题,但也会让代码里出现更多空值处理,适合对类型安全要求更高的项目逐步开启。

详细版

不开启时:

const list = ["a"];
const item = list[10]; // string

开启后:

const item = list[10]; // string | undefined

对象字典:

const map: Record<string, number> = {};
const count = map["missing"]; // number | undefined

这更符合运行时真实行为,因为访问不存在的属性会得到 undefined

完整版教学

一、索引访问的运行时真相

JavaScript 访问不存在的数组下标或对象属性会返回 undefined

const list = ["x"];
console.log(list[99]); // undefined

但默认 TypeScript 往往根据容器声明返回元素类型。

这个选项把“可能不存在”从运行时事实带回类型系统。

二、数组下标越界更容易暴露

function first(items: string[]) {
  return items[0].toUpperCase();
}

开启后,items[0]string | undefined

如果数组可能为空,就必须处理:

function first(items: string[]) {
  const item = items[0];
  return item ? item.toUpperCase() : "";
}

三、字典对象缺 key 更真实

const scores: Record<string, number> = {};
const score = scores["Ada"];

不开启时看起来是 number,实际可能是 undefined。

开启后变成:

const score: number | undefined = scores["Ada"];

这能避免把缺失值直接参与计算。

四、和可选链、空值合并配合

const label = labels[id] ?? "未知";

或者先判断:

const value = cache[key];
if (value !== undefined) {
  use(value);
}

如果 undefined 本身是合法值,就需要用 Object.hasOwn 判断 key 是否存在。

五、它不会改变明确属性访问

type User = {
  name: string;
};

declare const user: User;
user.name; // string

这个选项主要影响索引访问,不会把所有属性都变成可选。

访问方式可能变化
arr[i]undefined
dict[key]undefined
obj.name通常不变

六、迁移成本和策略

开启后,老项目可能出现大量报错。

建议:

  • 新项目直接开启
  • 老项目按目录逐步迁移
  • 先处理数据边界层
  • 对确实存在的值使用明确判断
  • 少用非空断言批量压错
const item = list[index]!;

! 应该是最后手段,不是迁移策略。

七、常见误区与追问

  • 误区:数组声明为 string[] 就保证任意下标都有 string。 越界访问仍然是 undefined。
  • 误区:Record<string, T> 表示所有字符串 key 都真实存在。 运行时普通对象可以缺任意 key。
  • 误区:开启后所有属性都会变可选。 主要影响索引访问。
  • 误区:用 ! 全部压掉就完成迁移。 这会绕过选项带来的安全收益。
  • 追问:如果 undefined 是合法值怎么办? 用 key 存在性判断区分缺 key 和值为 undefined。
  • 追问:适合什么时候开启? 新项目或高可靠项目更适合,老项目可渐进开启。

八、加强记忆

记忆图:

container[index] -> value | undefined
because index may not exist

回答时强调它贴近 JavaScript 运行时真实行为,再讲数组越界和字典缺 key 两个场景,最后补迁移成本。