兼容的功能类型

时间:2016-08-01 12:53:15

标签: typescript

假设我们有这段代码:

class MyEvent {
    timestamp:number;
}
class AEvent extends MyEvent{
    x:number;
    y:number;   
}
class BEvent extends MyEvent{
    key:string; 
}
var fn:(event:MyEvent)=>void;
function AE(event:AEvent){
    let x = event.x; //Ok, but BEvent hasn't 'x' property. 
}
fn = AE;
fn(new BEvent());

打字稿没有告知错误。对于打字稿,它是一个有效的代码。 我在打字稿操场上试了一下。 (1.8版)

如何强制使用打字稿来禁止它?

例如,在C ++中

class Base {
    public:
        int timestamp;
};

class B: public Base {
    public:
        char key; 
};
class A: public Base {
    public:
        int x;
        int y;
};


void fA(A *ptr) {}

void (*fn)(Base *ptr);


int main()
{
    A *a = new A();
    B *b = new B();

    fn = fA; //error: invalid conversion from 'void (*)(A*)' to 'void (*)(Base*)' 
    fn(b);
}

1 个答案:

答案 0 :(得分:2)

函数参数是bivariant以允许常见的javascript模式,即使在某些罕见的情况下可能发生某些运行时错误。

根据类型compatibility handbook

  

比较函数参数的类型时,赋值成功   如果source参数可以分配给目标参数,   或相反亦然。这是不健全的,因为呼叫者可能最终会成为现实   给定一个更专业的类型的函数,但调用   功能较少的专业类型。在实践中,这种错误   很少见,允许这样可以实现许多常见的JavaScript模式。

Why are function parameters bivariant?

  

总之,在TypeScript类型系统中,是否有问题   更具体的类型接受功能应该可以分配给a   接受较少特定类型的函数提供了先决条件的答案   是否应该赋予更具体类型的数组   一个不太具体的类型的数组。后者不是这样的   在绝大多数情况下,它不是一个可接受的类型系统,   所以我们必须对具体情况采取正确的权衡   函数参数类型。