有一个功能请求位于微软/TypeScript#48992原生支持这一点。不过,除非实现这一点,否则您可以通过多种方式制作自己的版本。
一种方法是与条件类型 and 索引访问类型, 像这样:
type KeysMatching<T, V> = {[K in keyof T]-?: T[K] extends V ? K : never}[keyof T];
然后取出属性匹配的键string
像这样:
const key: KeysMatching<Thing, string> = 'other'; // ERROR!
// '"other"' is not assignable to type '"id"'
详细地:
KeysMatching<Thing, string> ➡
{[K in keyof Thing]-?: Thing[K] extends string ? K : never}[keyof Thing] ➡
{
id: string extends string ? 'id' : never;
price: number extends string ? 'number' : never;
other: { stuff: boolean } extends string ? 'other' : never;
}['id'|'price'|'other'] ➡
{ id: 'id', price: never, other: never }['id' | 'price' | 'other'] ➡
'id' | never | never ➡
'id'
请注意您在做什么:
type SetNonStringToNever<T> = { [P in keyof T]: T[P] extends string ? T[P] : never };
实际上只是转变非字符串属性values into never
属性值。它没有触及按键。你的Thing
会成为{id: string, price: never, other: never}
。其按键与 的按键相同Thing
。与此的主要区别是KeysMatching
是你应该选择键,而不是值(所以P
并不是T[P]
).
Playground 代码链接