Câmpuri condiționale bazate pe valoarea altui câmp în interfață în Typescript
Așa cum spune titlul, încerc să creez o interfață care va avea câmpuri obligatorii, dar numai dacă un alt câmp are o anumită valoare.
De exemplu :
const schema = {
str: { type: 'string' },
nbr: { type: 'number' },
bool: { type: 'boolean' },
date: { type: 'date' },
strs: { type: ['string'] },
obj: { type: 'object' },
} as ISchema;
Vreau ca acest cod să-mi spună că câmpul obj lipsește o proprietate deoarece valoarea type este 'object'.
Am reușit să fac asta cu acest cod :
interface SchemaOptionsObject {
type: 'object' | ['object'] ;
properties: ISchema;
}
interface SchemaOptionsString {
type: 'string' | ['string'] ;
}
interface SchemaOptionsNumber {
type: 'number' | ['number'] ;
}
interface SchemaOptionsBoolean {
type: 'boolean' | ['boolean'];
}
interface SchemaOptionsDate {
type: 'date' | ['date'] ;
}
type SchemaOptions = SchemaOptionsString | SchemaOptionsNumber | SchemaOptionsBoolean | SchemaOptionsDate | SchemaOptionsObject;
export interface ISchema {
[key: string]: SchemaOptions;
}
Dar această soluție este mult prea repetitivă. Am încercat să o factorizez și am ajuns la o problemă:
export type SchemaAllowedTypes = 'string' | 'number' | 'boolean' | 'date' | 'object';
type SchemaOptionsObject<T extends SchemaAllowedTypes> =
T extends 'object' ?
{ properties: ISchema } :
{};
type SchemaOptions<T extends SchemaAllowedTypes> = {
type: T | T[];
} & SchemaOptionsObject<T>;
export interface ISchema {
[key: string]: SchemaOptions<SchemaAllowedTypes>;
}
Știu că nu funcționează din cauza T extends 'object', dar nu am nicio idee despre cum să verific valoarea lui T, există un cuvânt cheie care ar putea face asta?
Fac asta în mod greșit?
Mulțumesc pentru ajutorul tău!
Răspuns #1
Ce zici de asta?
export type SchemaAllowedTypes = 'string' | 'number' | 'boolean' | 'date' | 'object';
interface SchemaOptionsGeneric<T extends SchemaAllowedTypes>{
type: T | [T] ;
}
interface SchemaOptionsObject extends SchemaOptionsGeneric<"object">{
properties: ISchema;
}
type SchemaOptions = SchemaOptionsGeneric<"string"|"number"|"boolean"|"date"> | SchemaOptionsObject
export interface ISchema {
[key: string]: SchemaOptions;
}
