Условные поля на основе значения другого поля в интерфейсе в Typescript - PullRequest
0 голосов
/ 09 мая 2020

Как сказано в заголовке, я пытаюсь создать интерфейс , который будет иметь обязательные поля, но только если другое поле имеет определенное значение.

Например:

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, есть ли ключевое слово, которое могло бы сделать это?

Я делаю это неправильно?

Спасибо за вашу помощь!

...