Как сказано в заголовке, я пытаюсь создать интерфейс , который будет иметь обязательные поля, но только если другое поле имеет определенное значение.
Например:
const schema = {
str: { type: 'string' },
nbr: { type: 'number' },
bool: { type: 'boolean' },
date: { type: 'date' },
strs: { type: ['string'] },
obj: { type: 'object' },
} as ISchema;
Я хочу, чтобы этот код сообщал мне, что в поле obj
отсутствует свойство, потому что значение type
равно 'object'
.
Мне удалось сделайте это с помощью этого кода:
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;
}
Но это решение слишком повторяющееся. Я попытался разложить его на множители и столкнулся с проблемой:
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>;
}
Я знаю, что это не работает из-за T extends 'object'
, но я понятия не имею, как проверить значение T
, есть ли ключевое слово, которое могло бы сделать это?
Я делаю это неправильно?
Спасибо за вашу помощь!