如何获取`keyof T`的子集,其值T[K]是Typescript中的可调用函数 [英] How to get a subset of `keyof T` whose value, T[K] are callable functions in Typescript
问题描述
我想根据T[keyof T]
它应该是这样工作的:
type KeyOfType<T, U> = ...
KeyOfType<{a: 1, b: '', c: 0, d: () => 1}, number> === 'a' | 'c'
KeyOfType<{a: 1, b: '', c: 0: d: () => 1}, string> === 'b'
KeyOfType<{a: 1, b: '', c: 0: d: () => 1}, Function> === 'd'
这可能吗?
推荐答案
您可以使用条件和映射类型来做到这一点
You can do this using conditional and mapped types
type KeyOfType<T, U> = {[P in keyof T]: T[P] extends U ? P: never}[keyof T]
让我们把事情分解一下.
Let's break things down a little bit.
我们可以从一个映射类型开始,它具有与原始 T
相同类型的相同属性,这是一个简单的标准映射类型:
We can start with a mapped type, that has the same properties of the same type as the original T
, this a simple standard mapped type:
type KeyOfType<T> = { [P in keyof T]: T[P] } // New Type same as the original
T[P]
是一个类型查询,表示T
中键P
的类型.我们可以将其更改为 P
,这意味着新属性的类型与其名称相同:
T[P]
is a type query and means the type of the key P
in type T
. We can change this to just P
, meaning that the type of the new property is the same as it's name:
type KeyOfType<T> = { [P in keyof T]: P }
// So
KeyOfType<{ a: number, b: string }> == { a: 'a', b: 'b' }
我们可以给这个类型添加一个类型查询来再次获取该类型的所有键.通常,构造 T[keyof T]
获取类型的所有属性类型.将此应用于我们的映射类型,该类型的属性类型与我们基本上返回到 keyof T
的键名称相同:
We can add a type query to this type to again get all the keys of the type. Generally a construct T[keyof T]
gets all the property types of a type. Applying this to our mapped type which has the property types the same as the key names we basically get back to keyof T
:
type KeyOfType<T> = { [P in keyof T]: P }[keyof T]
// So
KeyOfType<{ a: number, b: string }> == 'a'|'b'
现在我们可以为 o not always select P
添加条件类型.由于 A |never == A
如果原始属性的类型 (T[P]
) 不满足某个约束,我们可以将映射类型中的属性类型设置为 never.
Now we can add a conditional type to o not always select P
. Since A | never == A
we can set the type of the property in the mapped type to never if the type of the original property (T[P]
) does not meet a certain constraint.
为了表达约束,我们添加了一个额外的泛型参数 U
并且我们使用了一个条件类型,其形式为 T extends U ?TypeIfTrue: TYPEIfFalse
.把它放在一起,我们得到:
To express the constraint we add an extra generic parameter U
and we use a conditional type which has the form T extends U ? TypeIfTrue: TYpeIfFalse
. Putting it together we get:
type KeyOfType<T, U> = {[P in keyof T]: T[P] extends U ? P: never}[keyof T]
这篇关于如何获取`keyof T`的子集,其值T[K]是Typescript中的可调用函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!