2017-05-10 5 views
5

Próbuję utworzyć typ ogólny, który pobiera nazwy właściwości i typy właściwości z typu i używa ich do utworzenia typu ujednoliconego związku. Na przykład:Tworzenie dyskryminowanej unii przy użyciu nazw właściwości innego typu

type FooBar = { 
    foo: string; 
    bar: number; 
}; 

będzie mapować do:

type FooBarPair = { 
    key: "foo", 
    value: string 
} | { 
    key: "bar", 
    value: number 
} 

Moja Pierwsza próba jest:

type Pairs<T> = { 
    [TKey in keyof T]: { 
     key: TKey; 
     value: T[TKey]; 
    }; 
}; 

type Pair<T> = Pairs<T>[keyof T]; 

ale gdy próbuję zastosować to do rodzaju powyżej:

let pair: Pair<FooBar> = { 
    key: "foo", 
    value: 3 
}; 

Spodziewałbym się błędu kompilacji, ale tam Chodź jeden. Kiedy sprawdzać typ Pair<FooBar> Uważam to równa się:

{ 
    key: "foo" | "bar"; 
    value: string | number; 
} 

myślę, że może to być błąd w maszynopisie, ale chciałem zobaczyć, czy jest jakiś inny sposób na osiągnięcie tego celu.

Odpowiedz

3

Tak, jest sposób na osiągnięcie tego. Okazuje się, że Typescript wnioskuje żądany typ

`{ key: "foo"; value: string; } | { key: "bar"; value: number; }` 

po wyjęciu pośredni ogólny typ type Pair<T> = Pairs<T>[keyof T]; i poszerzyć go inline jak Pairs<FooBar>[keyof FooBar] za każdym razem, byś użył go:

type Pairs<T> = { 
    [TKey in keyof T]: { 
     key: TKey; 
     value: T[TKey]; 
    }; 
}; 

type FooBar = { 
    foo: string; 
    bar: number; 
}; 


let pair: Pairs<FooBar>[keyof FooBar] = { 
    key: "foo", 
    value: 3 
}; 

kompletny komunikat o błędzie jest

Type '{ key: "foo"; value: number; }' is not assignable to type '{ key: "foo"; value: string; } | { key: "bar"; value: number; }'. 
    Type '{ key: "foo"; value: number; }' is not assignable to type '{ key: "foo"; value: string; }'. 
    Types of property 'value' are incompatible. 
     Type 'number' is not assignable to type 'string'. 

Nie jestem pewien, jaki typ "prawidłowy" można wywnioskować w obu przypadkach, ale wprowadzenie skrótów typu: Pair<T> = Pairs<T>[keyof T] nie powinno wpływać na wnioskowanie typu IMO. Wygląda jak błąd.

+0

Dzięki, zgadzam się, wydaje się, że to błąd, podniosę problem z maszynopisem. –

+0

[Problem] (https://github.com/Microsoft/TypeScript/issues/15756) został zgłoszony. –

+0

[Poprawka jest w zakładzie] (https://github.com/Microsoft/TypeScript/pull/18042) – artem