如何在TypeScript中从ConfigurationProperty元组推导组合类型?
可以自动推断类型T
完全可以从传入的ConfigurationProperty元组中自动推断出类型T,核心是让TypeScript保留元组中每个元素的具体类型信息,而非用宽泛的数组类型抹平细节。
步骤1:调整泛型与类型推导逻辑
将函数泛型与传入的props元组绑定,通过映射类型从元组中提取键值对结构:
import * as z from 'zod'; export type ConfigurationProperty<V> = { type: string; schema: z.Schema<V>; }; // 从ConfigurationProperty元组推导目标配置类型 type ConfigFromProps<P extends readonly ConfigurationProperty<any>[]> = { [K in P[number]['type']]: Extract<P[number], { type: K }>['schema'] extends z.Schema<infer V> ? V : never; }; // 重新定义validate函数 const validate = <P extends readonly ConfigurationProperty<any>[]>( data: Record<string, unknown>, props: P ): ConfigFromProps<P> => { // 用传入的props构建Zod验证schema const schemaObj = props.reduce((acc, prop) => { acc[prop.type] = prop.schema; return acc; }, {} as Record<string, z.Schema<any>>); const schema = z.object(schemaObj); // 验证数据并返回,自动匹配推导的类型 return schema.parse(data); };
步骤2:调用示例(自动推断生效)
给每个ConfigurationProperty对象加上as const以保留字面量类型,调用时无需手动指定T:
export const DailyStandupTime = { type: "dailyStandupTime" as const, schema: z.string(), } as const; export const DailyStandupTimeZone = { type: "dailyStandupTimeZone" as const, schema: z.string(), } as const; // TypeScript自动推断返回类型为 { dailyStandupTime: string; dailyStandupTimeZone: string } const result = validate( { dailyStandupTime: "09:00", dailyStandupTimeZone: "Asia/Shanghai" }, [DailyStandupTime, DailyStandupTimeZone] ); // result.dailyStandupTime 类型为string,类型检查完全生效
关键细节
as const确保type的字面量类型被保留,不会被拓宽为通用string类型。- 泛型参数
P约束为readonly ConfigurationProperty<any>[],让TypeScript记住元组中每个元素的具体类型,避免信息丢失。 ConfigFromProps映射类型遍历元组元素,提取type作为键,从schema中推断出对应的值类型。
内容的提问来源于stack exchange,提问作者Adam A
相关产品推荐
相关产品推荐

