为什么数组中的索引在TypeScript中打破了类型的安全性?

时间:2017-08-08 18:27:19

标签: javascript arrays typescript indexing types

向JavaScript添加静态类型的重点是提供有关类型安全性的一些保证。我注意到数组索引似乎打破了类型安全,而没有使用任何像as any或非空断言运算符这样的脏技巧。

let a: Array<number> = [1,2,3,4];
let b: number = a[4]; //undefined

此代码不会导致任何TypeScript错误,即使很明显它会违反类型安全性。在我看来,索引运算符Array<T>采取的[]类型应该是T | undefined类型,但TypeScript编译器将其视为类型T

经过进一步调查,我发现这种行为也适用于在对象上使用索引运算符。在任何情况下,索引运算符似乎都不是类型安全的。

class Example {
  property: string;
}

let c: Example = { property: "example string" }
let d: string = c["Not a property name"]; //undefined

在具有任意键返回类型any的对象上使用索引运算符,可以将其分配给任何类型而不会导致类型错误。但是,这可以通过使用--noImplicitAny编译器选项来解决。

我的问题是为什么像数组上的索引那样基本的东西打破类型安全?这是TypeScript的设计约束,疏忽还是故意的一部分?

2 个答案:

答案 0 :(得分:3)

要回答问题的为什么部分,是因为TypeScript的开发人员认为,如果在索引{时总是必须检查undefined结果,那将太不舒服了。 {1}}。

例如,以下代码将不进行类型检查:

Array

此外,由于JavaScript var arr: number[] var s = 0 for (var i in arr) { s += arr[i] } 可能是稀疏的,即使已知索引没有超出范围(如Array>= 0),您仍然可以获得< arr.length,因此似乎无法完全推断出实际的不安全索引。

有关更多信息,请参见问题TypeScript#13778TypeScript#11122

答案 1 :(得分:1)

  

对具有任意键的对象使用索引运算符返回类型any,可以将其分配给任何类型而不会导致类型错误。但是,这可以通过使用--noImplicitAny编译器选项来解决。

是。如果您需要严格的安全,请使用noImplicitAny。还strict:truestrictNullChecks以及其他人strict)。

  

我的问题是为什么像数组上的索引那样基本的东西打破类型安全?这是TypeScript的设计约束,疏忽还是故意的一部分?

有安全等级。 psql=> SELECT state, count(county), PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY "population2000") AS median FROM CENSUS GROUP BY state; state | count | median ----------------------+-------+---------- Alabama | 67 | 36583 Alaska | 24 | 7296.5 Arizona | 15 | 116320 Arkansas | 75 | 20229 ... 是最强的。您可以选择对代码的严格程度。

更多

来自https://basarat.gitbooks.io/typescript/content/docs/options/intro.html

  

也就是说,传统的编程语言在类型系统允许和不允许的范围之间存在硬边界。 TypeScript的不同之处在于它可以控制放置滑块的位置。