据我所知,对于任何类型 T,
keyof T
都将是 T 的公共属性名称,然后我看到了 keyof any
,这让我感到困惑。我能否简化 keyof any
为 any
?keyof T
都将是 T 的公共属性名称,然后我看到了 keyof any
,这让我感到困惑。我能否简化 keyof any
为 any
?keyof any
不是 any
。它是 string | number | symbol
。type PropKey = keyof any
// type PropKey = string | number | symbol
keyof
类型运算符的结果是该类型允许使用的所有键类型的联合。因此,keyof any
要求所有可能的键类型,因为any
类型允许您使用任何有效的键进行索引。但并非所有类型都是有效的键,因此keyof any
只是string | number | symbol
,而不是unknown
类型之类的东西:
declare const x: any;
x.str; // okay
x[123]; // okay
x[Symbol("")] // okay
x[new Date()] // error
x[false] // error
keyof any
的类型是在TypeScript标准声明文件中提供的PropertyKey
类型:(链接)。declare type PropertyKey = string | number | symbol;
PropertyKey
而不是 keyof any
。keyof any
的原因是,在 TypeScript 2.9 之前,keyof
操作符只会返回可分配给 string
的类型。从 TypeScript 2.9 开始,keyof
支持 number
和 symbol
键类型。而 PropertyKey
本身也是在 TypeScript 2.9 中引入的。
这意味着,如果你有任何需要同时支持 TypeScript 2.9 之前和之后版本的代码,你不能使用 PropertyKey
或 string | number | symbol
来适当地 约束键类型。但是你可以使用 keyof any
;在 TypeScript 2.8 及以下版本中,keyof any
返回值仅为 string
,而在此之后它返回 string | number | symbol
。因此,你可以编写类似于下面这样的代码:
type DateHolder<K extends keyof any> = { [P in K]: Date };
它将在两种情况下工作。不过,自TypeScript 2.8以来已经过了一段时间,并且自那时以来发生了许多重大变化,因此可能没有必要使用keyof any
。