为什么Typescript在索引到不可索引类型时不会出错,有没有办法让它这样做?

时间:2018-01-31 05:41:43

标签: typescript indexing type-safety

在尝试使用map类型的同时,我通过尝试使用方括号来设置元素来反复射击自己。我意识到我需要使用map.get(key)map.set(key,value)但是在使用Python和C#字典这么久之后,我很难通过我厚厚的头骨。

let m = new Map<string, string>();

// This doesn't generate any error, though it 
//  doesn't do what someone might assume it
//  would (doesn't add an element to the map)
m["foo"] = "bar"

// This doesn't generate an error either
m[1] = 2; 

// This does generate an error, even though
//  in javascript, m.foo means the same as 
//  m["foo"], so why does typescript treat
//  them differently?
m.foo = "bar"

// This is what someone really should be
//  doing to add an element to the map
m.set("baz", "qux")

我使用Typescript的原因通常是因为它阻止我做类型不支持的愚蠢的事情。但是,在这种情况下,Typescript不会出错。我似乎并不关心我是否试图使用方括号来索引地图。

事实上,即使对于像数字这样的原始数据类型,它也似乎不会像我这样完全废话:

// Typescript allows you to index into any
//  type, even a number?!??!?!
let x = 3;
let y = 4;
x["crazy"] = "yes";

// But again the behaviour is inconsistent
// between indexing with [] versus .
// The following is an error in Typescript.
x.crazy = "no"

甚至是我自己的班级。

class MyClass {
    x: number;
}

let myInstance = new MyClass()
myInstance.x = 5;
myInstance["y"] = 10; // not an error

我的问题是:

  1. 允许索引到任何和所有类型的Typescript的基本原理是什么?
  2. 考虑到x.foo与javascript中的x [&#34; foo&#34;]是同义词,为什么Typescript会以不同的方式对待它们?
  3. 有没有办法可以启用额外的检查,这些检查会阻止索引到不可编入索引的类型中?有没有办法将类型标记为不可索引,以便您不会意外地尝试将其编入索引?

2 个答案:

答案 0 :(得分:2)

使用默认的编译器设置,您确实可以索引到您不应该索引的对象。这可能是为了简化从JS到TS的迁移。

您可以使用noImplicitAny标志启用编译器关于索引(任何其他隐式使用)的检查,或者更一般地,您可以使用strict标志启用额外检查。

答案 1 :(得分:1)

允许索引的打字稿的基本原理是,javascript的模式的语义使用必须与打字稿相同。

在这方面,财产权限o.propertyo['property']有不同的期望,例如参见here

要添加更多注意事项,请考虑使用javascript:

let x = 1
x["crazy"] = "yes"
x.pazzo =  "no"

这可以通过这种方式转换为有效的打字稿:

declare let x: any;

x = 1
x["crazy"] = "yes";
x.pazzo = "no"

或以这种方式:

x = 1
x["crazy"] = "yes";
(<any>x).pazzo = "no"

x被声明/转换为任何形状,因此在这种情况下x.pazzo变为TS可分配。

上述行为使我们假设原始类型号具有索引签名[string]: any:这意味着可以像在JS中一样在TS中索引数字。

启用noImplicitAny选项后,数字不再允许使用索引签名[string]: any

error TS7017: Index signature of object type implicitly has an 'any' type.

最后回答最后一个问题集noImplicitAny: true,以便启用typescript来检查不可索引的类型。