为什么对象上的数组访问运算符([])不是错误?

时间:2018-10-01 12:35:57

标签: typescript tslint

在重构代码时,我偶然发现了我不理解的TypeScript编译器的奇怪行为。

interface IPoint {
    x: number;
    y: number;
}

let a: IPoint = { x: 5, y: 10 };
let b = a[0];
console.log(b);

在编译此代码时,我希望编译器由于访问a的键(在编译时)绝对不存在而引发错误。

那是为什么?是否有其他我不知道的TSLint选项标记[]被用作错误/警告对象?

最好的问候和预先的感谢

3 个答案:

答案 0 :(得分:4)

我强烈建议打开--strict compiler option。此选项将启用一堆额外的检查,这些检查对于捕获错误非常有用。根据您的情况,您可以通过--noImplicitAny选项进行特定的检查:

  

--noImplicitAny:使用隐式any类型的表达式和声明引发错误。

如果您将其打开,则会看到以下错误:

let b = a[0]; // error!
// Element implicitly has an 'any' type because type 'IPoint' has no index signature.

您可能会发现,如果打开--strict模式,还会出现许多其他错误。这很烦人,但是通常这些都是您应该处理的好错误,即使出现误报,处理这些错误也会使您的代码更好。

希望有所帮助;祝你好运!

答案 1 :(得分:3)

使用默认的编译器设置,typescript将允许使用任何键对任何对象进行索引操作(结果将为any类型)。要使此错误,请使用noImplicitAny编译器选项。

答案 2 :(得分:1)

在JavaScript中,[]不仅 是一个数组索引运算符,它还是一个property accessor,这意味着它可用于访问对象的属性,例如

const animal = {
  legCount: 4
};

console.log(animal.legCount); // 4
console.log(animal['legCount']); // 4

discussed here一样,TypeScript隐式地为所有索引提供类型any

  

JavaScript允许索引到任何对象。 TypeScript编译器无法静态知道类型检查的所有内容,例如var name = getName(); x[name];。因此它的类型为any

要添加某种程度的保护,您可以尝试添加索引签名并指定期望的类型。

interface IPoint {
    x: number;
    y: number;
    [key: string]: number; // This object will contain only number properties.
}