As the title says, I'm trying to create an interface that will have required fields but only if another field is of a certain value.
For example :
const schema = {
str: { type: 'string' },
nbr: { type: 'number' },
bool: { type: 'boolean' },
date: { type: 'date' },
strs: { type: ['string'] },
obj: { type: 'object' },
} as ISchema;
I want this code to tell me that the field obj
is missing a property because the value of type
is 'object'
.
I succeeded to do so with this code :
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;
}
But this solution is way too repetitive. I tried to factorise it and ended up with a 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>;
}
I know it doesn't work because of the T extends 'object'
but I have no idea on how to check the value of T
, is there a keyword that could do that ?
Am I doing this the wrong way ?
Thanks for your help !
hasvalue
ahah. Thanks anyway !