Тип не принимает ни одного или одного из двух свойств, но отклоняет оба

#typescript

#typescript

Вопрос:

Мне нужен тип, который не принимает ни одного или одно из двух свойств, но отклоняет их оба. Как это построить?

 interface I{
  ...
}
let a:I={} //accept empty
let b:I={f1:true} // accept only f1
let c:I={f2:true} // accept only f2
let d:I={f1:true,f2:true}//reject both of f1 and f2

  

Ответ №1:

Вы можете использовать объединение типов, имеющих свойства never types .

 type F1 = {
    f1: boolean; f2?: never;
}
type F2 = {
    f1?: never; f2: boolean;
}
type NotF = {
    f1?: never; f2?: never;
}
type I = F1 | F2 | NotF;
let a: I = {} //accept empty
let b: I = { f1: true } // accept only f1
let c: I = { f2: true } // accept only f2
let d: I = { f1: true, f2: true } //reject both of f1 and f2
  

NotF объявляется разрешающим {} .

Игровая площадка

Ответ №2:

Или вы могли бы использовать более общее решение:

 type Source = {
    p1: boolean;
    p2: number;
    p3: string;
}

type OneOfOrEmpty<T extends {
    [key: string]: any;
}, P extends keyof T = keyof T> = {
    [K in P]?: never; 
} | (P extends keyof T ? Pick<T, P> amp; {
    [K in keyof Omit<T, P>]?: never
} : never)

let test: OneOfOrEmpty<Source> | undefined;

test = {}; // works
test = { p1: true }; // works
test = { p2: 5 }; // works
test = { p3: "" }; // works
test = { p1: false, p3: "" }; // gives an error
  

Комментарии:

1. Идеальное решение!