打字稿:您如何将类型的属性过滤为特定类型的属性? [英] Typescript: How do you filter a type's properties to those of a certain type?
问题描述
我有一个界面
export interface MyInterface {
a: number;
b: string;
c: number;
}
我想创建一个文字类型的属性名称,其值为 number 类型
I want to create a literal type of the property names for which value is of type number
我知道如何使用
type MyType = keyof MyInterface // gives 'a'|'b'|'c'
我只想得到'a'|'c'
I want to get just 'a'|'c'
推荐答案
你当然可以在 TypeScript 中定义这样的类型:
You certainly can define such a type in TypeScript:
type KeysMatching<T extends object, V> = {
[K in keyof T]-?: T[K] extends V ? K : never
}[keyof T];
type MyType = KeysMatching<MyInterface, number>;
// type MyType = "a" | "c"
在此,KeysMatching
返回T
的属性可分配给V
的键集.它使用 条件和 mapped 类型以及属性 查找.对于keyof T
中的每个键K
,它检查T[K]
是否可分配给V
.如果是,则返回密钥K
;如果没有,它返回never
.因此,对于您的类型,它类似于 {a: "a", b: never, c: "c"}
.然后我们查找属性值并获得类型的联合,例如 "a" |从不|"c"
简化为 "a" |"c"
,完全符合您的要求.
In this, KeysMatching<T, V>
returns the set of keys of T
whose properties are assignable to V
. It uses a conditional and mapped type along with a property lookup. For each key K
in keyof T
, it checks whether T[K]
is assignable to V
. If so, it returns the key K
; if not, it returns never
. So for your types it would be something like {a: "a", b: never, c: "c"}
. Then we look up the property values and get a union of the types like "a" | never | "c"
which reduces to "a" | "c"
, exactly as you wanted.
请注意,KeysMatching
仅在读取属性时返回其值与 V
匹配的那些属性键.那些完全是 V
或 V
的子类型:
Do note that KeysMatching<T, V>
only returns those property keys whose values match V
when reading the property. Those that are exactly V
or a subtype of V
:
interface AnotherInterface {
narrower: 1;
exact: number;
wider: string | number;
}
type AnotherType = KeysMatching<AnotherInterface, number>;
// type AnotherType = "narrower" | "exact"
如果你想在编写一个T
的属性时,得到与V
匹配的键...也就是V
或V
的超类型,那么你需要一个不同的KeysMatching
实现:
If you want to get the keys which match V
when writing a property of T
... that is, exactly V
or a supertype of V
, then you need a different implementation of KeysMatching
:
type KeysMatchingWrite<T extends object, V> = {
[K in keyof T]-?: [V] extends [T[K]] ? K : never
}[keyof T];
type AnotherTypeWrite = KeysMatchingWrite<AnotherInterface, number>;
// type AnotherTypeWrite = "exact" | "wider"
无论如何,希望有所帮助.祝你好运!
Anyway, hope that helps. Good luck!
这篇关于打字稿:您如何将类型的属性过滤为特定类型的属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!