基于 Typescript 接口中另一个字段值的条件字段

Gal*_*anM 7 typescript typescript-generics typescript-typings

正如标题所说,我正在尝试创建一个界面具有必填字段的

例如 :

const schema = {
    str: { type: 'string' },
    nbr: { type: 'number' },
    bool: { type: 'boolean' },
    date: { type: 'date' },
    strs: { type: ['string'] },
    obj: { type: 'object' },
} as ISchema;
Run Code Online (Sandbox Code Playgroud)

我希望这段代码告诉我该字段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;
}
Run Code Online (Sandbox Code Playgroud)

但这个解决方案过于重复。我试图分解它,但最终遇到了一个问题:

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>;
}
Run Code Online (Sandbox Code Playgroud)

我知道它不起作用,因为T extends 'object'但我不知道如何检查T,是否有关键字可以做到这一点?

我这样做的方式不对吗?

感谢您的帮助 !

Fed*_*ico 1

这个怎么样?

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;
}
Run Code Online (Sandbox Code Playgroud)