开启strictNullChecks后TypeScript数组访问未报错的原因及解决办法
问题解答
为什么这段代码不会报错?
TypeScript 的索引签名(比如{ [key: number]: string })默认语义是:所有存在于对象中的键,对应的值类型为string,而非“所有可能的键的返回值类型”。
即使开启strictNullChecks,TypeScript 也不会自动为索引签名添加undefined类型——它默认假设你访问的键是存在于对象中的,因此this.arr[nr]会被推断为string,和get函数的返回类型string匹配,变量x的赋值自然也不会触发错误。但实际运行时,不存在的键会返回undefined,这就导致了类型系统和运行时的不一致。
如何触发预期的错误?
你需要修改索引签名的类型定义,显式声明不存在的键可能返回undefined,有两种常见方式:
方式1:修改索引签名为包含undefined的联合类型
export class Lala { id: number = Infinity; // 显式声明值类型为 string | undefined arr: { [key: number]: string | undefined } = {}; get(nr: number): string { return this.arr[nr]; // 此处会报错:类型“string | undefined”不能赋值给类型“string” } } const lala = new Lala(); const x: string = lala.get(555); // 此处也会报错
方式2:使用可选索引签名
可选索引签名(?:)和上述联合类型效果一致,写法更简洁:
export class Lala { id: number = Infinity; // 可选索引签名,表示键可能不存在,对应值为 string | undefined arr: { [key: number]?: string } = {}; get(nr: number): string { return this.arr[nr]; // 同样会触发错误 } } const lala = new Lala(); const x: string = lala.get(555); // 同样会触发错误
修改后,TypeScript 会识别到this.arr[nr]可能返回undefined,与get函数声明的返回类型string冲突,从而触发你预期的错误。
内容的提问来源于stack exchange,提问作者Paflow
相关产品推荐
相关产品推荐

