2017-04-04 2 views
1

のは、私は次の型マップを持っているとしましょう:インデックス付きの型マップを識別された共用体に展開できますか?

type MyTypes = { 
    'float': number; 
    'text': string; 
    'bool': boolean; 
    'price': number; 
    'date': Date; 
}; 

そして、私は自動的にそのための差別組合の種類を生成します。これの同等:そうのように使用することができ

type Datum<K, V> = { type: K, value: V }; 

type MagicUnionMaker<TypeMap> = (
    // pretend the below is auto-generated from TypeMap 
    Datum<'float', number> | 
    Datum<'text', string> | 
    Datum<'bool', boolean> | 
    Datum<'price', number> | 
    Datum<'date', Date> 
); 

interface DataModel<TypeMap> { 
    data(row: number, col: number): MagicUnionMaker<TypeMap>; 
} 

let model: DataModel<MyTypes>; 
let datum = model.data(0, 0); 
switch (datum.type) { 
    case 'float': 
    // datum.value is `number` 
    break; 
    case 'text': 
    // datum.value is `string` 
    break; 
    case 'bool': 
    // datum.value is `boolean` 
    break; 
    case 'price': 
    // datum.value is `price` 
    break; 
    case 'date': 
    // datum.value is `Date` 
    break; 
    case 'thing': // error 
    break; 
} 

この現在可能のようなものですか?

+0

AFAIKをユニオンにマッピングすることはできません(まだ)。私は組合の部分が人間によって書かれなければならないと思う。 – Jokester

答えて

3

ない、かなり、それはあなたが一般的なUnionMakerを持っており、インプレースあなたがそれを必要とするたびに、ユニオン型を構築する必要があることはできません表示されます。同等のジェネリック型が失敗した構築する

type MyTypes = { 
    'float': number; 
    'text': string; 
    'bool': boolean; 
    'price': number; 
    'date': Date; 
}; 

type TypeDataMap<T> = {[K in keyof T]: {type: K, value: T[K]}}; 

interface MyDataModel { 
    data(row: number, col: number): TypeDataMap<MyTypes>[keyof MyTypes]; 
} 

let model: MyDataModel; 
let datum = model.data(0, 0); 
// type inference works as expected 
switch (datum.type) { 
    case 'float': 
    let n: number = datum.value; 
    break; 
    case 'text': 
    let s: string = datum.value; 
    break; 
    case 'bool': 
    let b: boolean = datum.value; 
    break; 
    case 'price': 
    let p: number = datum.value; 
    break; 
    case 'date': 
    let d: Date = datum.value; 
    break; 
    case 'thing': // error: Type '"thing"' is not comparable to type 
       // '"float" | "text" | "bool" | "price" | "date"'. 
    break; 
} 

の試み:

// does not work 
type UnionMaker<T> = TypeDataMap<T>[keyof T]; 

type MyTypeMap = UnionMaker<MyTypes>; 
// because MyTypeMap gets inferred for some reason as 
// type MyTypeMap = { 
//  type: "float" | "text" | "bool" | "price" | "date"; 
//  value: string | number | boolean | Date; 
// } 
// which is NOT what you want 
関連する問題