我只是在学习TypeScript,而且我对any
的性质感到有些困惑。看看这个:
var x: any = 1;
var y = 1;
x = y;
y = x; // why does this not cause a compile-time error?
起初我理解any
是没有任何承诺的类型 - 这就是为什么第一个赋值是合理的 - 但看起来在其他上下文(第二个赋值)中,它可以是一个类型所有可以想象的承诺。
例如,这件疯狂事件也可以很好地编译:
undefined.foo
那是因为undefined
被认为是any
,这是一种承诺一切的类型。嗯。
将此与
对比var a : HTMLElement = new HTMLDivElement();
var b = new HTMLDivElement();
a = b;
b = a; // doesn't compile. phew.
在这里,我们可以得到一些强烈类型语言中更通用的东西:一个错误,作为一个显式的强制转换:
b = <HTMLDivElement>a; // ah, you mean it's really a div...
在大多数使用any
的情况下,我会期待类似unknown
的内容,定义为
interface unknown { }
将是更好的选择。
我首先遇到此问题,因为我的代码使用eval
来解析json。 eval
返回any
,这意味着TypeScript认为您可以使用它完成所有操作,而无需任何强制转换。
我认为这显然是错的。将该问题与其他类型语言的工厂进行比较,例如C#:
(MyType)Activator.Create(typeof(MyType)) // cast is needed
或C ++:
// cast is needed in C++ (not in C, though I think it really should...)
(MyType*)malloc(size);
每当我有一个产生无类型的函数的函数时,我希望在我可以将它用于任何事情之前我需要先抛出它。
所以我的问题是:
any
,类似于上面的unknown
,是否是标准的?any
如此突出,另一个如此隐藏?答案 0 :(得分:8)
对于第一个问题,等同于unknown
的是{}
,空类型。当没有其他类型可以计算时,编译器有时会产生{}
(例如,在['foo', 42]
中,元素类型为{}
之前,它变为string|number
并添加了union类型)。
接下来,经常提到any
的原因是,关于TypeScript的典型抱怨是它具有太多类型的强制执行,而不是太少。 JavaScript程序员似乎并不是一直在编写类型转换器。显然这是一个品味问题,但事实就是如此。
这一切都在设计上,因为TypeScript的核心方案是获取现有的JavaScript,并根据需要添加尽可能多的类型信息,而不会产生大量的吨数和大量的错误。每当TypeScript看到没有类型注释但无法推断其类型的内容时,它将使用any
,因为这是允许大多数JavaScript编译而没有错误的类型。
版本1.1中修复了undefined.foo
。它现在可以正确报告错误(TypeScript中undefined
和null
的确切处理是一个有趣但独立的讨论。)
史蒂夫提到,noImplicitAny
可以提供帮助。当某些类型any
没有明确的类型注释时,它会引发错误。
答案 1 :(得分:7)
any
类型是一种特殊类型。在可能的情况下,除非您想利用动态类型,否则应避免使用any
类型。
any
类型是一种简短的说法......
将此变量视为与任何其他类型兼容。
所以你可以将它分配给一个字符串,一个数字,一个数组,一个对象,一个具有任何结构的接口......任何东西都可以。
因此,不要将其视为any
类型,如果我将其分配给字符串,请将其视为“字符串”
您可以通过传递any
编译器标志(或将项目设置设置为使用此标志)来避免意外使用--noImplicitAny
类型。