2016-08-01 85 views
0

讓我們說我們有這樣的代碼:兼容類型的函數

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

回答

2

該函數的參數是雙變量,以允許即使在一些罕見的病例發生一些運行時錯誤常見的JavaScript圖案。

根據compatibility handbook類型:

當比較類型的函數的參數,分配成功 如果源參數是分配給所述目標參數, 或反之亦然。這是不合適的,因爲調用者可能最終得到 給定一個函數,該函數採用更專門化的類型,但調用 函數的專用類型較少。實際上,這種類型的錯誤 很少見,並允許啓用許多常見的JavaScript模式。

Why are function parameters bivariant?

綜上所述,在打字稿類型的系統中,一個 更特異型接受功能是否應該分配給一個 函數接受無特定類型提供的問題一個先決條件回答 指出是否可將更具體類型的數組分配給 一個不太特定類型的數組。後者不是 在絕大多數情況下都不是可接受的類型系統,因此我們必須針對 函數參數類型的具體情況進行正確性權衡。

+0

很好的答案。我的結論是,我的情況是'某些運行時錯誤可能發生在極少數情況下。「 – Oleg