索引器内部和外部的keyof有什么区别?

时间:2018-11-15 23:49:12

标签: typescript generics type-alias

假设我们有以下TypeScript代码:

type ForwardVal<T> = { 
    [K in keyof T]: string; 
};
type ForwardKeyOf<T extends string | number | symbol> = { 
    [K in T]: string; 
};

type ByObj   = ForwardVal<number[]>;         // string[]
type ByKeyOf = ForwardKeyOf<keyof number[]>; // { length: string, toString: string, ... }

type foo =   ByObj['push'];   // (...items: string[]) => number
type bar = ByKeyOf['push'];   // string

为什么foo不是字符串,而bar是字符串?转发keyof obj和转发Key in T本身使obj并在映射类型内部进行Key in keyof T之间有什么区别? T参数不是仅由其给定值代替吗?

1 个答案:

答案 0 :(得分:2)

通常没有什么区别,keyof只是keyof参数中存在的所有键(属性和方法名称)的联合类型。

但是从TypeScript 3.1开始,有一种特殊情况-使用与keyof相同的语法来创建mapped types over tuples and arrays

  

在TypeScript 3.1中,现在可以在元组和数组上映射对象类型   产生新的元组/数组,而不是创建新的元组/数组   像push(),pop()和length这样的成员都将被转换。

因此,当存在统一(同态)映射类型时

type ForwardVal<T> = { 
    [K in keyof T]: string; 
};

,它的参数T是一个元组或数组类型(在您的情况下是ForwardVal<number[]>),然后如文档所述,“仅数字属性被转换”,产生string[]作为结果类型。