// 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;
我理解T
是string
的子类型所以我期待类型系统以某种方式迭代o
的成员T
的数组[K in o]: K;
。像List<decimal>
之类的东西,但我知道编译时静态分析没有意义。任何人都可以指点我一个资源,以了解如何更好地“思考类型”吗?感谢。
答案 0 :(得分:2)
// 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
类型为&#34; AA&#34; | &#34; BB&#34;
你已经知道如何在类型中思考,你只是不相信自己。这正是发生的事情。只需更换&#34;许多字符串&#34;使用&#34;许多文字字符串子类型&#34;,因为从类型系统的角度来看,当你调用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']);