TypeScript:从任何东西到任何东西的隐式演员?

Joh*_*ohn 9 typescript

我只是在学习TypeScript而且我对它的性质感到有点困惑any.看看这个:

var x: any = 1;
var y = 1;
x = y;
y = x; // why does this not cause a compile-time error?
Run Code Online (Sandbox Code Playgroud)

起初我理解any为没有任何承诺的类型 - 这就是为什么第一项任务合理可行 - 但似乎在其他情境(第二项任务)中,它可以是一种具有所有可以想象的承诺的类型.

例如,这件疯狂也编译得很好:

undefined.foo
Run Code Online (Sandbox Code Playgroud)

那是因为undefined假设是any,这是一种承诺一切的类型.嗯.

对比这个

var a : HTMLElement = new HTMLDivElement();
var b = new HTMLDivElement();
a = b;
b = a; // doesn't compile. phew.
Run Code Online (Sandbox Code Playgroud)

在这里,我们得到了我希望通过强类型语言为更特殊的东西分配更通用的东西:错误,作为显式强制转换是必要的:

b = <HTMLDivElement>a; // ah, you mean it's really a div...
Run Code Online (Sandbox Code Playgroud)

在大多数使用的情况下any,我会期待类似的unknown定义为

interface unknown { }
Run Code Online (Sandbox Code Playgroud)

会是一个更好的选择.

我第一次遇到这个问题,因为我的代码eval用于解析json.eval返回any,这意味着TypeScript认为您可以使用它执行所有操作,而无需任何强制转换.

我认为这显然是错的.将该问题与其他类型语言的工厂(例如C#)进行比较:

(MyType)Activator.Create(typeof(MyType)) // cast is needed
Run Code Online (Sandbox Code Playgroud)

或者C++:

// cast is needed in C++ (not in C, though I think it really should...)
(MyType*)malloc(size); 
Run Code Online (Sandbox Code Playgroud)

每当我有一个产生无类型的函数的函数时,我会期望在我可以将它用于任何事情之前我需要先抛出它.

所以我的问题是:

  1. 有类似于any上面的unknown标准吗?
  2. 如果是这样,为什么any特色突出而另一个如此隐藏?
  3. 这个问题是在某个地方提出的吗?有没有人可以链接的讨论?

Rya*_*ugh 9

对于第一个问题,相当于,unknown{}空类型.编译器将有时会产生{}当没有其他类型可以计算(例如,在['foo', 42]中,元素类型是{}在它变得string|number与加成联合类型的).

接下来,any经常提到的原因是关于TypeScript的典型抱怨是它有太多的类型强制执行,而不是太少.JavaScript程序员似乎并不是一直在编写类型转换器.显然这是一个品味问题,但它就是它的本质.

这一切都非常符合设计,因为TypeScript的核心方案是获取现有的JavaScript,并根据需要添加尽可能多的类型信息,而不会产生大量的吨数和大量的错误.每当TypeScript看到没有类型注释的东西时,其类型无法推断,它将被使用,any因为这是允许大多数JavaScript编译而没有错误的类型.

undefined.foo事被固定在1.1版本.现在正确地报告错误(确切的治疗undefined,并null在打字稿是有趣的,但单独讨论).

正如史蒂夫提到的那样,noImplicitAny是否有帮助.当某些类型any没有显式类型注释时,它会引发错误.


Fen*_*ton 8

any类型是一种特殊类型.在可能的情况下,any除非要利用动态类型,否则应避免使用该类型.

这种any类型是一种简短的说法......

将此变量视为与其他任何类型兼容.

所以你可以将它分配给一个字符串,一个数字,一个数组,一个对象,一个具有任何结构的接口......任何东西都可以.

所以,不要把它看成是一个any类型,把它想成是"一个字符串,如果我把它分配给一个字符串 ".

您可以any通过传递--noImplicitAny编译器标志(或将项目设置设置为使用此标志)来避免意外使用该类型.

  • 感谢`--noImplicitAny`。在实践中有帮助。(对于其他VS用户:您可以在“ TypeScript Build”选项卡的项目选项中将其打开。) (2认同)