在Typescript类型`in`运算符周围的混乱

时间:2017-04-27 10:10:35

标签: typescript

following code

// 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的数组[K in o]: K; 。像List<decimal>之类的东西,但我知道编译时静态分析没有意义。任何人都可以指点我一个资源,以了解如何更好地“思考类型”吗?感谢。

1 个答案:

答案 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']);