2016-03-21 6 views
5

Rozważmy następujący fragment (patrz również TS Playground):Zadzwoń new Date z Union Typ "numer | string"

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 

To ostateczna linia daje błąd kompilatora:

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

Jednakże, ponieważ istnieje konstruktor Date(...) dla obu typów, które zakładam, że powyższe będzie działać.

mogę obejść ten problem, ponieważ nie ma innego konstruktora biorąc any parametr:

myDate = new Date(<any> both); 

ale co jeśli konstruktor nie było, na przykład czy ten scenariusz wystąpił w mojej własnej klasie?

Czy jest jakiś sposób, aby to działało poprawnie? Czy też typ związków ma tu charakterystyczny zapach, co oznacza, że ​​moje definicje muszą zostać zmienione?

Sprawdziłem TS Handbook, ale nie ma sekcji o typach związków. Próbowałem go rozwiązać samodzielnie, ale nie pominąłem wyżej wspomnianej sztuczki <any>. Przeszedłem przez sugerowane duplikaty i podobne pytania na temat SO, ale nie znalazłem na razie odpowiedzi.

Odpowiedz

4

Można rozszerzyć interfejs konstruktora Date, aby obsługiwać to; Prawdopodobnie nie najładniejszy rozwiązaniem, ale wydaje się działać ...

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 

myślę rodzaje związkowe są traktowane jako obywateli pierwszej klasy w maszynopisie, czyli na przykład: string | number ma swój własny rodzaj, do którego string lub number można przypisać. Pod tym względem value: string i value: number nie pasują do podpisu typu value: string | number - dlatego sensowne jest przedłużenie DateConstructor w celu obsługi tego.

3

Zostało to omówione powyżej w projekcie Github skryptu.

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

Podsumowując, byłoby miło mieć tę pracę w prostych sytuacjach, takich jak ten, który już prezentowane, ale w bardziej skomplikowanych sytuacjach rozpada.

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.

Ich sugestia polega na wprowadzeniu standardów kodowania, które mówią, że typy funkcji powinny raczej używać typów złącz niż przeciążeń.

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

To jest znakomita informacja, dziękuję. Zaakceptowałem drugą odpowiedź, ponieważ jest to rozwiązanie (/ workaround), którego użyłem, ale również +1 tutaj! – Jeroen

+0

@Jeroen To ma dla mnie sens! Chociaż wydaje mi się, że dostarczyłem użytecznych/interesujących informacji, serial0ne bezpośrednio odpowiedział na pytanie w ten sposób. Dzięki za awans :) – AndyJ

Powiązane problemy