在重构代码时,我偶然发现了我不理解的TypeScript编译器的奇怪行为。
interface IPoint {
x: number;
y: number;
}
let a: IPoint = { x: 5, y: 10 };
let b = a[0];
console.log(b);
在编译此代码时,我希望编译器由于访问a
的键(在编译时)绝对不存在而引发错误。
那是为什么?是否有其他我不知道的TSLint选项标记[]
被用作错误/警告对象?
最好的问候和预先的感谢
答案 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.
}