我有一个界面
export interface MyInterface {
a: number;
b: string;
c: number;
}
我想创建属性名称的文字类型,其值的类型为数字
我知道如何使用所有属性名称获取类型
type MyType = keyof MyInterface // gives 'a'|'b'|'c'
我只想得到'a'|'c'
答案 0 :(得分:1)
您当然可以在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>
返回属性T
可分配给V
的一组键。它使用conditional和mapped类型以及属性lookup。对于K
中的每个键keyof T
,它检查T[K]
是否可分配给V
。如果是这样,它将返回键K
;如果不是,则返回never
。因此,对于您的类型,它类似于{a: "a", b: never, c: "c"}
。然后,我们查询属性值,并获得"a" | never | "c"
之类的类型的并集,该类型会完全按照您的需要缩减为"a" | "c"
。
请注意,读取属性时,KeysMatching<T, V>
仅返回其值与V
匹配的属性键。完全是V
或V
子类型的那些
interface AnotherInterface {
narrower: 1;
exact: number;
wider: string | number;
}
type AnotherType = KeysMatching<AnotherInterface, number>;
// type AnotherType = "narrower" | "exact"
如果您想在写入 V
的属性时获取与T
匹配的键...正好是V
或 V
的 ,那么您需要使用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"
无论如何,希望能有所帮助。祝你好运!
答案 1 :(得分:0)
不要以为您可以按类型选择属性,但是如果您知道接受的属性,则可以基于这样的属性创建一个新类型;
type MyType = Pick<MyInterface, 'a' | 'c'>
我喜欢this blog post,它涵盖了大多数类型(Readonly
,Partial
,Required
,Pick
,Record
,{{1 }},Extract
等),但我知道Exclude
也是最近引入的。
我发现这个答案可以更好地解释它; Exclude property from type