2016-10-13 46 views
0

如果問題的聯合類型包含任何類型的用戶定義的類別,我發現typescript 2.0.3編譯器會在沒有投訴的情況下編譯無效的賦值。Typescript聯合類型一旦聯合中包含自定義類別就會停止區分

例子:

class Bar {} 

// Complains as expected: 
interface Foo { 
    bar: number|string 
} 

// Does not complain, surprisingly: 
interface Foo2 { 
    bar: number|string|Bar 
} 

var a = <Foo> { 
    bar: 5 
}; 
var a2 = <Foo> { 
    bar: "yar" 
}; 
//var a3 = <Foo> { 
// bar: new Date() // compiler complains as expected. 
//}; 

var b = <Foo2> { 
    bar: new Date() // compiler does not complain, I am confused. 
}; 

編譯器錯誤,我得到的時候我去掉a3是:

lib/src/thing.ts(18,10): error TS2352: Type '{ bar: Date; }' cannot be converted to type 'Foo'. 
    Types of property 'bar' are incompatible. 
    Type 'Date' is not comparable to type 'string | number'. 
     Type 'Date' is not comparable to type 'number'. 

我希望分配b時收到相同的錯誤,但毫無怨言編譯就好了。

這是一個已知的問題?或者這是預期的行爲,我不明白爲什麼這應該被認爲是有效的?我希望能夠依靠聯合類型來確保財產是幾件事情之一,包括我自己定義的類別,因此任何見解都將得到最多讚賞。

謝謝,提前!


編輯:我做了一些更多的測試,並以更爲簡單的例子上來:

class Bar {} 

var a = <string|number> 4; 
var b = <string|number> "thing"; 
var c = <string|number> new Bar(); // works: confusing 
var d = <Bar> 4;     // ... confusing 
var f = <number> new Bar();  // ... also confusing 

回答

1

打字稿使用duck typing,爲written in the docs

One of TypeScript’s core principles is that type-checking focuses on the shape that values have. This is sometimes called 「duck typing」 or 「structural subtyping」

由於您Bar類是空的,編譯器設法匹配Date對象與Bar,因爲沒有矛盾秒。
但是,一旦你的成員或方法添加到您Bar會得到一個錯誤:

class Bar { 
    x: number; 
} 

var b = <Foo2> { 
    bar: new Date() 
}; 

產地:

Type '{ bar: Date; }' cannot be converted to type 'Foo2'. 
    Types of property 'bar' are incompatible. 
    Type 'Date' is not comparable to type 'string | number | Bar'. 
     Type 'Date' is not comparable to type 'Bar'. 
     Property 'x' is missing in type 'Date'. 

code in playground

+0

雖然技術上,鴨打字是不是真的與結構分型相同。鴨子打字更多的是運行時現象,只關心使用過的成員的存在,而結構打字則是類型的編譯時間比較。 – Alex

相關問題