2017-04-27 18 views
1

following code混亂周圍打字稿類型`in`操作者

// This makes sense 
type simpleKeys = 'a' | 'b'; 
let anObject: { 
    [index in simpleKeys]: string; 
} = {a: 'a', b: 'b'}; 
anObject.a; // 'a' 

// This doesn't make sense, how does `T` have many types? It is only 
// a subtype of type `string`... or is the act of invoking the function 
// with many strings allowing the compiler to infer that `T` is of 
// type "AA" | "BB"? 
function strEnum<T extends string>(o: Array<T>): {[K in T]: K} { 
    return o.reduce((res, key) => { 
    res[key] = key; 
    return res; 
    }, Object.create(null)); 
} 

const LABELS = strEnum(['AA', 'BB']); 

type LABEL = keyof typeof LABELS; 

我明白Tstring亞型所以我期待的類型系統,以超過o其成員是陣列以某種方式遍歷T s。就像[K in o]: K;,但我知道這對於編譯時靜態分析沒有意義。任何人都可以指點我的資源,以瞭解如何「更好地思考類型」好一點嗎?謝謝。

回答

1
// This doesn't make sense, how does `T` have many types? It is only 
// a subtype of type `string`... or is the act of invoking the function 
// with many strings allowing the compiler to infer that `T` is of 
// type "AA" | "BB"? 

或者是調用函數與許多字符串讓編譯器推斷T類型爲「AA」的行爲| 「BB」?

你已經知道如何在類型中思考,你只是不相信自己。這正是發生的情況。簡單地將「多個字符串」替換爲「多個字符串子類型」,因爲從類型系統的角度來看,當調用strEnum(['AA', 'BB'])時發生了什麼。

strEnum(['AA', 'BB']) 
// is the same as 
strEnum(['AA', 'BB'] as ['AA', 'BB']); 
// or, to put it another way 
strEnum(['AA' as 'AA', 'BB' as 'BB']); 
// or, a third way 
strEnum<'AA' | 'BB'>(['AA', 'BB']);