2017-08-25 6 views
1

したがって、typecriptで見つかった秘訣は、タイプをキーと値のペアにマッピングしてから、keyofタイプを使用してマップ内の任意の値にすることによって、オブジェクトタイプを識別されたユニオンに変換することです。ここでは簡単な例です:ハードコーディングされたタイプとは異なるセマンティクスを持つジェネリックの[typof T]の理由は?

type SourceType = 
{ 
    foo: number, 
    bar: string 
}; 
type MapWithKey<T> = {[P in keyof T]: { key: P, value: T[P] }} 
type DescriminatedUnion = MapWithKey<SourceType>[keyof SourceType]; 
//The DescriminatedUnion now has the following type 
DescriminatedUnion ≡ {key:"foo",value:string} | {key:"bar",value:number} 

あなたはあなたが別のタイプで終わるこの構築物は、完全に汎用的にするためにしようとすると、しかし、非常に大きな判別組合を指定したい場合、これは非常に便利です。

type MakeDescriminatedUnion<T> = MapWithKey<T>[keyof T]; 
type DescriminatedUnion = MakeDescriminatedUnion<SourceType> 
//The DescriminatedUnion now has the followin type 
DescriminatedUnion ≡ {key:"foo"|"bar",value:number|string} 

これは同じタイプである必要がありますが、何らかの理由でそうではありません。私はtypescriptのドキュメントを見て、この動作の理由を見つけようとしましたが、私はできません。この違いの背後にある理由を知っている人はいますか?それとも、誰かがこの振る舞いを回避して完全に汎用化する方法を知っていますか?

+3

[この質問](https://stackoverflow.com/questions/43898999/creating-a-discriminated-union-using-the-property-names-of-another-type)は非常によく似ています、ここでは[github問題](https://github.com/Microsoft/TypeScript/issues/15756)、[こちらの修正プログラム](https://github.com/Microsoft/TypeScript/pull/18042) – artem

+0

ありがとうございました!それは私の予想以上のものです。 @artem –

答えて

1

はい、とquite数はothersです。はい、this issueです。 @artemが言及しているように、a fixがTypeScript 2.6向けに発表されたのはすごいことです。

一方、活字体2.4-土地で立ち往生たちのもののために、default generic type parametersを使用して回避策があります:

type MakeDiscriminatedUnion<T, M extends MapWithKey<T> = MapWithKey<T>> = M[keyof T]; 
type DiscriminatedUnion = MakeDiscriminatedUnion<SourceType> // okay now 

Mの実際の値は、あなたがMakeDiscriminatedUnion<SourceType>を使用するまで評価され、そのコンパイラがありません。 M[keyof T]上記のやり方を「単純化」する機会はありません。

いずれにしても、回避策を使用するのか、TypeScript 2.6を待つのはあなたの選択です。希望が役立ちます。がんばろう!

+0

ありがとうございました!どこにでも見つけられませんでした! –

関連する問題