如何编写 PickByValue 类型?

Posted

技术标签:

【中文标题】如何编写 PickByValue 类型?【英文标题】:How to write PickByValue type? 【发布时间】:2019-08-04 15:41:24 【问题描述】:

Pick 类型包含在 TypeScript 中。其实现如下:

type Pick<T, K extends keyof T> = 
  [P in K]: T[P];
;

您将如何编写 PickByValue 类型以使以下工作:

type Test = 
  includeMe: 'a' as 'a',
  andMe: 'a' as 'a',
  butNotMe: 'b' as 'b',
  orMe: 'b' as 'b'
;

type IncludedKeys = keyof PickByValue<Test, 'a'>;
// IncludedKeys = 'includeMe' | 'andMe'

【问题讨论】:

您希望PickByValue&lt;Test, 'a' | 'b'&gt; 等同于Test 还是等同于 【参考方案1】:

假设您打算将Test 变成这样:

type Test = 
  includeMe: 'a',
  andMe: 'a',
  butNotMe: 'b',
  orMe: 'b'
;

并假设您希望PickByValue&lt;T, V&gt; 提供所有属于V子类型 的属性(因此PickByValue&lt;T, unknown&gt; 应该是T),那么您可以定义PickByValue像这样:

type PickByValue<T, V> = Pick<T,  [K in keyof T]: T[K] extends V ? K : never [keyof T]>
type TestA = PickByValue<Test, 'a'>; // includeMe: "a"; andMe: "a"
type IncludedKeys = keyof PickByValue<Test, 'a'>; // "includeMe" | "andMe"

但如果你想要的只是IncludedKeys,那么你可以更直接地使用KeysMatching&lt;T, V&gt;

type KeysMatching<T, V> = [K in keyof T]: T[K] extends V ? K : never[keyof T];
type IncludedKeysDirect = KeysMatching<Test, 'a'> // "includeMe" | "andMe"

Playground link to code

【讨论】:

经过思考后,我意识到KeysMatching 对于我的特定用例来说更灵活一些。我在最初的尝试中接近了目标,但还没有达到目标。非常感谢!

以上是关于如何编写 PickByValue 类型?的主要内容,如果未能解决你的问题,请参考以下文章

如何编写类型安全的联合类型化保存方法

MySQL - 如何在过程中编写查询? (SET 数据类型参数)

如何编写返回多种数据类型值的Java函数?

如何在 Typescript 中编写严格要求其参数的函数类型

我们如何在 Hive 中为自定义 Writable 类型编写自定义 ObjectInspector?

如何在不编写长查询的情况下查询所有 GraphQL 类型字段?