如何编写 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<Test, 'a' | 'b'>
等同于Test
还是等同于
?
【参考方案1】:
假设您打算将Test
变成这样:
type Test =
includeMe: 'a',
andMe: 'a',
butNotMe: 'b',
orMe: 'b'
;
并假设您希望PickByValue<T, V>
提供所有属于V
的子类型 的属性(因此PickByValue<T, unknown>
应该是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<T, V>
:
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 数据类型参数)
如何在 Typescript 中编写严格要求其参数的函数类型