【问题标题】:Compatible types in functions函数中的兼容类型
【发布时间】:2016-08-01 21:43:04
【问题描述】:

假设我们有这个代码:

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());

Typescript 不会通知错误。对于打字稿,它是一个有效的代码。 我在打字稿操场上试过了。 (1.8版本)

如何强制 typescript 禁止它?

例如,在 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);
}

【问题讨论】:

    标签: typescript


    【解决方案1】:

    函数参数是双变量的,以允许常见的 javascript 模式,即使在极少数情况下可能会发生一些运行时错误。

    根据输入compatibility handbook

    比较函数参数类型时,赋值成功 如果任一源参数可分配给目标参数, 或相反亦然。这是不合理的,因为来电者可能最终会成为 给定一个函数,该函数采用更特殊的类型,但调用 具有较少特殊类型的函数。在实践中,这种错误 很少见,并且允许这样做会启用许多常见的 JavaScript 模式。

    Why are function parameters bivariant?

    总之,在 TypeScript 类型系统中,是否 更具体的类型接受功能应该分配给 接受不太具体的类型的函数提供了先决条件答案 是否应该将更具体类型的数组分配给 一个不太具体的类型的数组。后者并非如此 在绝大多数情况下不会是可接受的类型系统, 所以我们必须对特定情况进行正确性权衡 函数参数类型。

    【讨论】:

    • 好答案。我得出的结论是,我的情况是“在极少数情况下可能会发生一些运行时错误。”
    猜你喜欢
    • 1970-01-01
    • 2019-09-18
    • 1970-01-01
    • 1970-01-01
    • 2015-03-02
    • 2014-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多