如何编写 PickByValue 类型?

Bra*_*ell 5 typescript

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

type Pick<T, K extends keyof T> = {
  [P in K]: T[P];
};
Run Code Online (Sandbox Code Playgroud)

你将如何编写一个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'
Run Code Online (Sandbox Code Playgroud)

jca*_*alz 8

假设你打算Test是这样的:

type Test = {
  includeMe: 'a',
  andMe: 'a',
  butNotMe: 'b',
  orMe: 'b'
};
Run Code Online (Sandbox Code Playgroud)

并假设你想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"
Run Code Online (Sandbox Code Playgroud)

但是,如果您想要的只是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"
Run Code Online (Sandbox Code Playgroud)

Playground 链接到代码