TypeScript:将接口转换为类

时间:2013-02-20 12:16:30

标签: typescript

我有以下代码:

interface X {
    type : string;
    val : number;
}

class X1 implements X {
    type : string;
    val : number;
}

var p1 : X[] = [{type:'a', val:8}];

for (var n in p1) {
    var p2 : X1 = p1[n];
}
var p3 : X1 = p1[0];

p2和p3都声明为类型X1,并使用类型X的值进行初始化。

编译器很乐意接受p2的声明,但它抱怨p3说“无法将'X'转换为'X1'”。

为什么会出现这种差异?

1 个答案:

答案 0 :(得分:6)

实施X的所有内容都应该可以转换为X,但不一定能转换为X1

这里有更多细节。下面的代码显示了一个简单的示例。从本质上讲,如果你有类型X(接口)的东西,它可以由X1(类)或X2(类)实现。

虽然你可以降级类型(从实现到接口),但你无法升级类型(从接口到特定的实现),因为你不能保证你拥有的是兼容的。

另一种看待这种情况的方法是,你可以制作一些 less 特定的东西,但是你不能制作一些更多特定的东西。

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循环。通常用于迭代对象和when you use it on an array it will only show explicitly set indexes (not all items)中的属性。要遍历数组,您应该使用:

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