Tìm kiếm trang web

Các trường điều kiện dựa trên giá trị của trường khác trong giao diện trong Typescript


Như tiêu đề đã nói, tôi đang cố gắng tạo một giao diện sẽ có các trường bắt buộc nhưng chỉ khi một trường khác có giá trị nhất định.

Ví dụ :

const schema = {
    str: { type: 'string' },
    nbr: { type: 'number' },
    bool: { type: 'boolean' },
    date: { type: 'date' },
    strs: { type: ['string'] },
    obj: { type: 'object' },
} as ISchema;

Tôi muốn mã này thông báo cho tôi biết rằng trường obj đang thiếu một thuộc tính vì giá trị của type là 'object'.

Tôi đã thành công làm điều đó với đoạn mã này:

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;
}

Nhưng giải pháp này lặp đi lặp lại quá nhiều. Tôi đã cố gắng phân tích nó và cuối cùng gặp một vấn đề:

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ôi biết nó không hoạt động vì T extends 'object' nhưng tôi không có ý tưởng gì về cách kiểm tra giá trị của T, có từ khóa nào có thể làm điều đó không?

Tôi đang làm điều này sai cách sao?

Cảm ơn bạn đã giúp đỡ!

Câu trả lời #1

Cái này thì sao?

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;
}

Bài viết liên quan