Фильтровать ключи типа, используя другой тип - PullRequest
0 голосов
/ 28 апреля 2018

Я пытаюсь создать тип, который будет рекурсивно исключать ключи из одного типа, если они не появляются в другом. Например, даны два типа:

type TargetType = {a: true, b: {c: true, d: true}};
type InputType = {a: string, b: { c: boolean, d: number, e: string }, f: number};

Я хочу создать универсальный тип PickMatchedKeys<T, U> такой, что

PickMatchedKeys<InputType, TargetType> = {a: string, b: { c: boolean, d: number }}

У кого-нибудь есть идеи, как этого добиться? Вот моя лучшая попытка:

type PickMatchedKeys<T, U> = {
    [K in keyof T]: K extends keyof U ? PickMatchedKeys<T[K], U[K]> : never;
}

Это работает нормально, но проблема в том, что ключи f и b.e все еще существуют в PickMatchedKeys<InputType, TargetType>, но имеют тип never. В идеале эти ключи вообще не должны присутствовать в конечном типе.

1 Ответ

0 голосов
/ 28 апреля 2018

Почему бы не так:

type PickMatchedKeys<T, U> = {
  [K in (keyof T) & (keyof U)]: 
    T[K] extends object ? PickMatchedKeys<T[K], U[K]> : T[K];
}

Вам не нужны условные типы, чтобы ограничивать ключи теми, которые являются общими как для T, так и U, поскольку вы можете просто пересекать типы ключей. Единственное, что вам нужно сделать, - это не углубляться в примитивы; вот где появляется часть T[K] extends object. Вы должны решить, хотите ли вы какой-то другой критерий (например, сделать что-то особенное с массивами), но это основной план.

Давайте рассмотрим это:

type TestIt = PickMatchedKeys<InputType, TargetType>;
declare const z: TestIt;
z.a // string
z.b.c // boolean
z.b.d // number
z.b.e // error
z.f // error

Хорошо выглядит для меня. Надеюсь, это поможет; удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...