2016-03-21 25 views
5

考慮下面的代碼片段(見TS Playground):呼叫與工會類型的新日期「號|串」

var nr: number = 123456; 
var str: string = "2015-01-01T12:00:00"; 
var both: number | string = 123456; 

var myDate: Date; 

myDate = new Date(nr); 
myDate = new Date(str); 
myDate = new Date(both); // <-- Compile error 

這最後一行給出了一個編譯器錯誤:

Argument of type number | string is not assignable to parameter of type 'string'. Type 'number' is not assignable to type 'string'.

然而,由於有一個Date(...)這兩種類型的構造函數我會假設上述將工作。

我可以解決該問題,因爲有另一個構造服用any參數:

myDate = new Date(<any> both); 

但是,如果它們的構造是不存在的,例如如果這種情況發生在我自己的班級?

有沒有什麼辦法讓它正常工作?或者是聯盟類型的設計氣味,這表明我的定義需要改變?

我檢查了TS Handbook,但它沒有關於聯合類型的部分。我試着自己解決它,但沒有超過上面提到的<any>技巧。我已經通過了SO上的建議副本和類似問題,但到目前爲止還沒有找到答案。

回答

4

你可以擴展Date的構造函數接口來支持這個;也許不是最好的解決方案,但它似乎工作...

interface DateConstructor { 
    new (value: number | string): Date; 
} 

var nr: number = 123456; 
var str: string = "2015-01-01T12:00:00"; 
var both: string | number = "123456"; 

var myDate: Date; 

myDate = new Date(nr); 
myDate = new Date(str); 
myDate = new Date(both); // <-- No more compile error 

我認爲聯合類型爲打字稿一等公民對待,也就是說,例如:string | number是它自己的類型,其中stringnumber可以分配。在這方面,value: stringvalue: number與類型簽名value: string | number不匹配 - 因此有必要擴展DateConstructor以支持這一點。

3

這已經在Typescript github項目上討論過了。

https://github.com/Microsoft/TypeScript/issues/1805

總之,這將是不錯的,就像你提出的一個簡單的情況下,這工作,但在更復雜的情況下,它分崩離析。

Essentially the overload set was used to create information tying the type of argument 1 to the type of argument 2 (and can be used likewise to tie this to a return type). With a union type that information is lost and any combination of argument types becomes allowed.

他們的建議是有適當的編碼標準,說功能類型應該使用聯合類型而不是重載。

See #6735 - we discussed and our plan is to mitigate this by providing a TS Lint rule and guidance that you should never write a series of overloads which have an equivalent representation in union types.

Somehow making this work as part of signature overload resolution is just way too complicated.

+0

這是很好的信息,謝謝。我已經接受了其他答案,因爲它是我最終使用的解決方案(/解決方法),但此處也是+1! – Jeroen

+0

@Jeroen這對我有意義!雖然我認爲我提供了有用/有趣的信息,但seriesOne直接用這種方式回答了問題。感謝upvote :) – AndyJ