Для данной пары свойств самое близкое приближение, которое вы можете сделать, чтобы потребовать оба свойства или ни того, ни другого, является объединением типа с обоими свойствами и типом с необязательными свойствами типа never
(что предотвращает присутствие свойств со значением, отличным от undefined
). Я получил идею от этого ответа . Это даст вам ошибку в правильных случаях, хотя сообщение об ошибке может быть не особенно полезным. Затем вы можете просто пересекать объединения для всех пар свойств, которые вы хотите (при условии, что у вас не более 10 пар, потому что когда TypeScript упрощает тип, он распределяет пересечения объединений, создавая объединения пересечений, что взорвать размер типа в геометрической прогрессии). Для вашего примера:
type AllOrNone<T> = T | {[K in keyof T]?: never};
type MyType = AllOrNone<{
message1: string;
minLength1: number;
}> & AllOrNone<{
message2: string;
minLength2: number;
}>;
Если вас действительно беспокоит случай undefined
и вы хотите использовать универсальную функцию для проверки ваших объектов вместо записи одного типа, тогда вы можете сделать что-то вроде этого:
type CheckAllOrNone<A, T> =
T | (keyof A & keyof T extends never ? {} : never);
type CheckMyType<A> = CheckAllOrNone<A, {
message1: string;
minLength1: number;
}> & CheckAllOrNone<A, {
message2: string;
minLength2: number;
}>;
function checkMyType<A extends CheckMyType<A>>(arg: A) {
return arg;
}