You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从TypeScript对象的Body数组中动态推导类型?

TypeScript动态推导Body类型问题

我有如下TypeScript对象:

export const MyVariable = {
        'test': {
            protected: false,
            body: [
                {
                    field: 'name',
                    type: 'string',
                    validators: ['MAX_CHAR_16']
                },
                {
                    field: 'surname',
                    type: 'string',
                }
            ]
        }
    }

尝试动态推导其中body对应的类型,目前使用双重推断写法:

type InferBodyType<T extends { body?: readonly SchemaField[] }> = T['body'] extends readonly SchemaField[]
    ? {
          [K in T['body'][number] as K['field']]: ExtractSchemaFieldType<K>;
      }
    : unknown;

type ExtractSchemaFieldType<T extends SchemaField> = T['type'] extends 'string' ? string : T['type'] extends 'number' ? number : unknown;

但由于body是数组,无法正确提取类型,当前结果始终为unknown,期望得到类似{name: string; password: string}这样的类型。希望无需定义大量类型和接口实现该需求。

完整代码示例:

export type CustomSchema<TComponent> = {
    [key: string]: CustomSchemaDefinition<TComponent>;
};

export type CustomSchemaDefinition<TComponent> = {
    method: HttpMethods;
    fnToCall: keyof TComponent;
    /** If true, checks for the token in the header  */
    protected?: boolean;
    body: SchemaField[];
};

export const BODY_VALIDATOR = {
    MAX_CHAR_16: /^.{1,16}$/,
    SPECIAL_CHAR: /^(?=.*[!@#$%^&*()_+{}\[\]:;<>,.?~\\/-]).+$/,
    EMAIL: /^[a-zA-Z0-9._%+-]{1,32}@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
};


export type SchemaField = {
    field: string;
    type: 'string' | 'number';
    validators: (keyof typeof BODY_VALIDATOR)[];
};

export type HttpMethods = 'post' | 'get' | 'put' | 'patch' | 'delete';


export const SCHEMA__AUTH: CustomSchema<any> = {
    'test': {
        protected: true,
        method: 'post',
        fnToCall: 'create',
        body: [
            {
                field: 'username',
                type: 'string',
                validators: ['MAX_CHAR_16']
            },
            {
                field: 'password',
                type: 'string',
                validators: ['MAX_CHAR_16', 'SPECIAL_CHAR']
            }
        ]
    }
} as const;



type FieldMap = { string: string, number: number };

type Body<T extends { field: string, type: string }> = { [U in T as U["field"]]: U["type"] extends keyof FieldMap ? FieldMap[U["type"]] : unknown }
type MyBody2 = Body<typeof SCHEMA__AUTH['test']['body'][number]>;
/* type MyBody = {
    name: string;
    surname: string;
} */

内容的提问来源于stack exchange,提问作者Jacopo Sciampi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 00:07:01