在JavaScript中添加静态类型的目的是为类型安全提供一些保证。我注意到,数组索引似乎破坏了类型安全性,而不使用任何肮脏的技巧,如as any或null断言操作符。
let a: Array<number> = [1,2,3,4];
let b: number = a[4]; //undefined这段代码不会导致任何TypeScript错误,尽管很明显,它会违反类型安全。在我看来,由索引运算符[]执行的Array<T>类型应该是T | undefined类型,但是TypeScript编译器将其视为T类型。
经过进一步研究,我发现这种行为也适用于对对象使用index操作符。在任何情况下,索引运算符似乎都不是类型安全的。
class Example {
property: string;
}
let c: Example = { property: "example string" }
let d: string = c["Not a property name"]; //undefined对具有任意键的对象使用索引运算符将返回any类型,可以将该类型赋值给任何类型,而不会导致类型错误。但是,可以通过使用--noImplicitAny编译器选项来解决这个问题。
我的问题是,为什么像数组中断类型的索引这样基本的东西是安全的呢?这是TypeScript的一个设计约束,一个疏忽,还是一个故意的部分?
发布于 2020-02-29 22:58:54
要回答您问题的部分原因,这是因为TypeScript的开发人员认为,如果在索引Array时总是必须检查undefined结果,那就太不舒服了。
例如,以下代码将不进行类型检查:
var arr: number[]
var s = 0
for (var i in arr) {
s += arr[i]
}此外,由于JavaScript Array的索引可能是稀疏的,即使已知索引不超出界限(如in、>= 0和< arr.length),仍然可以获得undefined,因此似乎无法完全推断实际的不安全索引。
有关这方面的更多信息,请参见TypeScript#13778和TypeScript#11122问题。
发布于 2017-08-09 00:01:49
对具有任意键的对象使用索引运算符,可以将其赋值给任何类型,而不会导致类型错误。但是,可以使用-noImplicitAny编译器选项来解决这一问题.
是。如果您关心严格的安全,请使用noImplicitAny。还有strict:true ( strictNullChecks以及其他)。
我的问题是,为什么像数组中断类型的索引这样基本的东西是安全的呢?这是TypeScript的一个设计约束,一个疏忽,还是一个故意的部分?
有一定程度的安全。strict是最强的。您可以选择对代码的要求有多严格。
更多
来自https://basarat.gitbooks.io/typescript/content/docs/options/intro.html
也就是说,传统的编程语言在类型系统允许的和不允许的语言之间有一个硬的界限。TypeScript的不同之处在于它可以让您控制放置滑块的位置。
发布于 2022-06-16 21:30:12
由于类型记录版本4.1,我们有设置noUncheckedIndexedAccess。启用该功能基本上与您所描述的类似-推断类型的索引访问始终包括undefined。在您的示例中,b的类型变成了T | undefined。
https://stackoverflow.com/questions/45575554
复制相似问题