Выбор ответа Senior Условные и mapped-типы обновлено
Omit на дискриминированном объединении
Вопрос
Почему после Omit пропало сужение?
type Ev = { kind: 'click'; x: number; ts: number } | { kind: 'key'; key: string; ts: number };
type NoTs = Omit<Ev, 'ts'>;
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Правильный ответ: Omit не распределяется: keyof Ev даёт только общие ключи, и x, key теряются. Omit<T, K это Pick<T, Exclude<keyof T, K, а keyof объединения даёт только общие ключи (kind, ts).
Варианты ответа
Omitне распределяется:keyof Evдаёт только общие ключи, иx,keyтеряютсяправильный ответOmitработает только с интерфейсами, а у type-алиасов объединения ломается- Сужение пропадает из-за
ts: number, которое есть в обоих вариантах объединения Omitудаляет вместе сtsи полеkind, потому что оно литерального типа
Разбор
Omit<T, K> это Pick<T, Exclude<keyof T, K>>, а keyof объединения даёт только общие ключи (kind, ts). Поэтому x и key теряются, и union схлопывается. Решение: распределительная версия type DistOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never. С интерфейсами Omit работает так же, а kind никто не удалял.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.