实现的所有东西都X
应该可以转换为X
,但不一定可以转换为X1
。
这里有更多细节。下面的代码显示了一个简单的示例。本质上,如果你有某种类型X
(接口),它可以由X1
(类)或X2
(类)实现。
虽然您可以降级一个类型(从实现降级到接口),但您不能升级一个类型(从接口到特定实现),因为您不能保证您所拥有的是兼容的。
另一种看待这个问题的方法是,你可以做一些比它更具体的东西,但你不能做一些比它更具体的东西。
interface X {
type : string;
val : number;
}
class X1 implements X {
type : string;
val : number;
}
class X2 implements X {
type: string;
val: number;
myMethod() {
}
}
var x1 = new X1();
var x2 = new X2();
var exampleA: X = x1; // happy
var exampleB: X = x2; // happy
var exampleC: X1 = exampleA; // Not happy...
所有这一切的结果是你需要强制转换它:
var exampleC: X1 = <X1>exampleA; // happy...
但要小心,因为你可以这样做,这实际上是行不通的:
var exampleC: X2 = <X2>exampleA; // seems happy...
exampleC.myMethod(); // oh dear!
更新
关于这段代码...
for (var n in p1) {
var p2 : X1 = p1[n];
}
在 JavaScript 中,这不等同于foreach
循环。这通常用于迭代对象中的属性,当您在数组上使用它时,它只会显示显式设置的索引(不是所有项目)。要遍历数组,您应该使用:
for (var i = 0; i < p1.length; i++) {
var p2 : X1 = p1[i]; // same warning as before
}
那么 TypeScript 是如何允许p1[n]
分配给X1
变量的呢?有趣的问题和答案就在这里...
如果您将鼠标悬停在上方,p1[n]
您会看到一个类型X[]
- 这是 的类型p1
,而不是 的类型p1[n]
。如果你检查这个例子,你会发现它p1[n]
的类型是any
:
var example = p1['test']; // I used 'test' because n is a string.
因为它是类型any
,所以编译器允许你告诉它把它当作一个X1
. 因此,您正在从转换any
为X1
不X
转换X1
为您可能认为的转换。