В дополнение к правильному замечанию @ kingdaro о лишних проверках свойств литералов объекта,
Определение Omit<T,K>
просто расширяет тип T
, так что он не содержит известного свойство на K
(«Я не знаю или мне все равно, если K
- это свойство; я буду игнорировать его».), Что не то же самое, что , запрещающий свойство на K
.То есть T
является подтипом Omit<T, K>
, и любое значение типа T
также можно будет присвоить типу Omit<T, K>
.Если вы намерены на самом деле запретить свойство на K
, вы можете (вроде) сделать это, указав, что свойство K
является необязательным и имеет тип значения never
(или undefined
, см. Ниже).Давайте назовем это ForcefullyOmit<T, K>
:
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
type ForcefullyOmit<T, K extends keyof T> = Omit<T, K> & Partial<Record<K, never>>;
И давайте посмотрим, работает ли оно:
interface ObjInterface {
first: string;
second: string;
}
const obj = {
first: "first",
second: "second"
};
const out: ForcefullyOmit<ObjInterface, "first"> = obj; // error
// types of property "first" are incompatible
// string is not assignable to undefined
Хорошо выглядит.
Это только «своего рода» запрет ключа, поскольку он по-прежнему допускает свойство для этого ключа типа undefined
(или never
), но это вроде нерешенная проблема в TypeScript ... язык не всегда различает отсутствующие свойства и undefined
.
Это зависит от вас, если ваш вариант использования действительно требует более строгого поведения ForcefullyOmit
.Во всяком случае, надеюсь, что это помогает;удачи!