繁体   English   中英

TypeScript:将接口转换为类

[英]TypeScript: Convert interface to class

我有以下代码:

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'”。

为什么会有这种差异?

实现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 那么,你是从转换anyX1不是从XX1 ,你可能会想到。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM