将上述代码放到编辑器中,obj[key]
会提示 ‘类型“string”无法用于索引类型“T”’
function foo<T extends { [k: string]: string } = { [k: string]: string }>(key: string): T | null {
const obj = {} as T;
obj[key] = 'asd';
return key ? obj : null;
}
但是下面这种情况却不会报错
const a: string = 'a';
const obj: { [K: string]: string } = {
[a]: '123',
};
为什么上面那种情况就无法索引对象呢?
感觉这个应该跟你类型断言的时机有关系,当你断言
obj
为泛型T
的时候,obj
就变成泛型T
的一个具体实例了,虽然泛型T
表示它的key索引是字符类型,value也是字符类型,但对于它的实例,多一个字段和少一个字段就是不同的类型了,它们之间不能安全的转换。所以如你上面所说的示例,可行的写法是:
或者如果就一个字段:
当然上面的方式更具有普遍性,下面的写法能比较直观地看出你提前断言与后断言的差别。