如何从只读对象数组Schema动态生成TypeScript接口?
从只读对象数组生成对应类型的正确实现
要生成匹配数组中name和value类型的接口,你可以通过以下两种方式修改类型定义:
方式一:利用类型推断(infer)
type Config<T extends ReadonlyArray<{ name: string; value: unknown }>> = { [K in T[number]['name']]: T[number] extends { name: K; value: infer V } ? V : never; }; // 你的只读配置 const config = [ { name: 'a', value: 1 }, { name: 'b', value: 'xx' }, ] as const; // 生成目标类型 type Res = Config<typeof config>; // 最终 Res 类型为:{ a: 1; b: "xx"; }
方式二:使用Extract查找匹配元素
type Config<T extends ReadonlyArray<{ name: string; value: unknown }>> = { [K in T[number]['name']]: Extract<T[number], { name: K }>['value']; }; const config = [ { name: 'a', value: 1 }, { name: 'b', value: 'xx' }, ] as const; type Res = Config<typeof config>; // 最终 Res 类型为:{ a: 1; b: "xx"; }
关键逻辑说明
- 两种写法的核心都是为每个键
K,精准定位数组中name等于K的元素,提取其value的类型 - 由于你给
config加上了as const,TypeScript会保留所有字面量类型的细节,所以能准确生成对应类型 - 如果需要把字面量类型转为基础类型(比如把
1转为number,"xx"转为string),可以在提取类型时加上类型约束,例如:type Config<T extends ReadonlyArray<{ name: string; value: unknown }>> = { [K in T[number]['name']]: Extract<T[number], { name: K }>['value'] extends infer V ? V extends number ? number : V extends string ? string : V : never; };
内容的提问来源于stack exchange,提问作者Yu Chen
相关产品推荐
相关产品推荐

