为什么这个Typescript对象不能分配给泛型类型T,它是一个包含对象类型的Union

时间:2017-07-04 03:58:38

标签: typescript generics

显然是一个人为的例子,但为什么我无法将类型为ISpeaker3的对象分配给包含ISpeaker3的联合的泛型类型?为什么需要下面显示的双重演员。

interface ISpeaker {
    greeting: string;
    speak: Function;
}

interface ISpeaker1 extends ISpeaker {
    introduction: string;
    firstArgument: string;
}

interface ISpeaker2 extends ISpeaker {
    secondArgument: string;
}

interface ISpeaker3 extends ISpeaker {
    rebuttal: string;
}

class Speaker3 implements ISpeaker3 {
    public greeting: string = "hello I'm Speaker Three."
    public rebuttal: string = "what a lot of nonsense!"
    speak(){console.log(this.greeting + this.rebuttal)}
}

class Debate<T extends ISpeaker | ISpeaker3> {
    speakers: Array<T>
    randomSpeaker: T
    constructor(spkrs: Array<T>) {
        for (let s of spkrs) {
            if (s.constructor.name === 'Speaker3') {
                (s as ISpeaker3).rebuttal = "Some other argument..." // OK. 
                let tempSpeaker = s as ISpeaker as ISpeaker3 // OK, but why the double cast necessary?
                this.randomSpeaker = tempSpeaker // Error - ISpeaker3 is not assignable to type T
            }
            else this.randomSpeaker = s // OK
        }
    }
}

2 个答案:

答案 0 :(得分:1)

可以在这里找到解释:

Narrowing breaking changes #7662

让我引用:

  

类型缩小对函数和类表达式中捕获的变量不起作用

export class Class {
    constructor(public p) { }
}

var c: Class | string;
var x: Class;

if (c instanceof Class) {
    function inner() {
        x = c; // Error, type of c is not narrowed, c is Class | string
    }
    x = c; // OK, c is Class
}

答案 1 :(得分:0)

试试这个:let tempSpeaker = s as T & ISpeaker3;