Обобщения TypeScript с рекурсией, условными и соответствующими ключами - PullRequest
0 голосов
/ 17 января 2019

У меня есть следующий тип с 2 общими параметрами:

type Result<INPUT, SPEC> = ...

Тип бетона Result зависит от различных комбинаций INPUT и SPEC.

Как это должно работать:

if(INPUT extends {[key: string]: any}) {
  if(SPEC extends {[key: string]: any}) {
    Result = {[key in keyof INPUT]: SPEC[key] !== undefined
            ? Result<INPUT[key], SPEC[key]>
            : true
    }
  } else {
    // ...
  }
} else {
  // ...
}

На словах:

  • Если INPUT и SPEC являются объектами, тогда Result должен быть объектом с ключами INPUT.
  • Для каждого ключа INPUT: проверьте, содержит ли SPEC тот же ключ
  • Если true, то значение для этого ключа равно Result<INPUT[key], SPEC[key]>
  • Если false, то значение для этого ключа равно true

Дополнительная информация:

  • Если INPUT и SPEC являются объектами, то SPEC является подмножеством INPUT. Это означает: INPUT может быть { foo: 42, bar: 42 }, но SPEC может содержать только foo или bar или оба, либо быть пустым.

Возможно ли это как-то с помощью TypeScript?

1 Ответ

0 голосов
/ 17 января 2019

Исходя из вашего описания, этот тип должен выполнить свою задачу:

export type Result<INPUT, SPEC> = INPUT extends object ? SPEC extends object ? {
    [K in keyof INPUT]: SPEC extends Record<K, infer SPECK> ?
        Result<INPUT[K], SPECK> :
        true
} : never : never;

// r is { foo: true; bar: never; goo: { a: never; b: true; }; }
type r = Result<{
    foo: number,
    bar: string,
    goo: { a: number; b: string }
}, { bar: number,  goo: { a: number }}>

Часть, которую вы, вероятно, пропустили, - SPEC extends Record<K, infer SPECK>, это проверяет, расширяет ли тип запись с помощью ключа K ипомещает тип этого ключа в SPECK.

Вы не указали явно, что происходит в ветвях else (если какой-либо из параметров типа не является объектом, поэтому я помещаю туда never, но вы можете настроить его так, как вам нужно)

Пустья знаю, что если я не понял все правильно, мы можем внести необходимые изменения.

...