这是一个错误或功能吗?我不确定

时间:2016-10-16 12:14:45

标签: generics typescript

不确定,应该在这里张贴,但这是我降落的地方......

注释中的

错误消息显示在下面的行中。为什么会显示这些错误?特别是错误#1因为T扩展了ITest所以它应该是安全的...

interface ITest {
    answer?: number; // error #1 dissapears if '?' is removed
}

class Base<T> {
    obj: T;
}

class Derived<T extends ITest> extends Base<T> {
    constructor() {
        super();

        var obj = { answer: 42 };

        // ok ... no suprise here
        var test:ITest = obj as ITest;

        // #1 Neither type { answer: number } or type T is assignable to each other.
        var t:T = obj as T;

        // this works ... (why? - specially when 1. dont...)
        var t2:T = obj as ITest as T;

        // #2 Type { answer: number } is not assignable to type 'T'.
        // #3 Cannot convert type { answer: number } to type T. Type parameter T is incompatible with { answer: number }, with is not type parameter.
        this.obj = obj;

        // #4 Type ITest is not assignable to type 'T'.
        // #5 Cannot convert type ITest to type T. Type parameter T is incompatible with ITest, with is not type parameter.
        this.obj = test;

        // this works
        this.obj = obj as any;

        // in this case error is not shown even if 'answer' is required in ITest ... 
        // (expected: 'Type { totally: string } is not assignable to type 'T'.)
        this.obj = { totally: 'different' } as any;
    }
}

欢呼声

1 个答案:

答案 0 :(得分:0)

似乎所有这些错误都来自两个问题,但在我们找到它们之前,您需要了解typescript如何比较类型,以及using duck typingmore on duck typing):< / p>

  

TypeScript的核心原则之一是类型检查的重点   价值观的形状。这有时被称为“鸭子打字”或   “结构子类型”

在您的代码中执行此操作:

$char = array('A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C');
sort($char);
print_r($char);

此处var obj = { answer: 42 }; 不是obj,而是{&n;类型为ITest,编译器会尽可能将其与{ answer: number }匹配,但这并不能使ITest成为obj类型。
如果您希望它为ITest,则需要执行以下操作:

ITest

或者

var obj = { answer: 42 } as ITest;

如果您将var obj: ITest = { answer: 42 }; 定义为obj,则错误#1消失(包含或不包含可选属性),这也是您在此处未收到错误的原因:

ITest

其余的错误是由于var t2: T = obj as ITest as T; 不是T,而是扩展了它。
例如,如果我有:

ITest

然后现在:

interface ITest2 extends ITest {
    question: string;
}

let c = new Derived<ITest2>();

有问题,因为var obj: ITest = { answer: 42 }; ... this.obj = obj; 的类型为obj,但ITest必须属于this.obj类型。

您可以告诉编译器相信您知道自己在做什么:

ITest2

your code with no error in playground

当您转换为this.obj = obj as T; this.obj = test as T; 时,您基本上会告诉编译器不要键入check,这就是为什么您没有收到错误的原因:

any