Выбор ответа Senior Утилитарные типы обновлено

Omit на объединении

Вопрос

Какой тип получит NoId?

type A = { kind: 'a'; a: number; id: string };
type B = { kind: 'b'; b: number; id: string };
type NoId = Omit<A | B, 'id'>;

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: { kind: 'a' 'b' }. Omit не распределяется по объединению. keyof (A B) это только общие ключи: 'kind' 'id'.

Варианты ответа

  1. Ошибка компиляции
  2. Omit<A, 'id'> | Omit<B, 'id'>
  3. { kind: 'a' | 'b' }правильный ответ
  4. { kind: 'a' | 'b'; a: number; b: number }

Разбор

Omit не распределяется по объединению. keyof (A | B) это только общие ключи: 'kind' | 'id'. После исключения 'id' остаётся Pick<A | B, 'kind'>, то есть { kind: 'a' | 'b' }. Поля a и b пропали, дискриминированное объединение сломалось.

Ожидаемый кандидатами результат Omit<A, 'id'> | Omit<B, 'id'> даёт распределённая версия: type DistributiveOmit<T, K extends PropertyKey> = T extends any ? Omit<T, K> : never. Ошибки компиляции нет.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.