Är det möjligt att villkorligt kräva en egenskap i ett Typescript-gränssnitt
Säg att jag har följande gränssnitt:
interface updateOptions {
updateAll: boolean;
fields: string[];
}
Finns det ett sätt att göra updateAll obligatoriskt när Fields inte tillhandahålls och vice versa, eller är detta något som måste göras villkorligt i implementeringen?
Svar #1
Använd märkt unionstyp:
type UpdateOptions =
| {updateAll: true}
| {updateAll: false, fields: string[]}
På detta sätt kan du bara initiera {updateAll: true} eller {updateAll: false, fields: ['someField', /*...*/]}
Tekniskt sett behöver unionen inte ha en tagg (boolean updateAll), men då behöver du definiera en typvakt för att testa vilken typ som används i en viss gren (jag antar att någonstans i din kod kommer du göra if (options.updateAll) {/* ... */}):
type UpdateAllOptions = {updateAll: true}
type UpdateSomeOptions = {fields: string[]}
type UpdateOptions = UpdateAllOptions | UpdateSomeOptions
// See https://www.typescriptlang.org/docs/handbook/advanced-types.html#user-defined-type-guards
const isAllOptions = (options: UpdateOptions): options is UpdateAllOptions =>
(options as any).updateAll === true
