打字稿:您如何将类型的属性过滤为特定类型的属性? [英] Typescript: How do you filter a type's properties to those of a certain type?

查看:23
本文介绍了打字稿:您如何将类型的属性过滤为特定类型的属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个界面

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 匹配的那些属性键.那些完全是 VV 的子类型:

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匹配的键...也就是VV超类型,那么你需要一个不同的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆