假设我们有以下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
参数不是仅由其给定值代替吗?
答案 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[]
作为结果类型。