如何在TypeScript中递归映射不规则嵌套的Theme类型为表单类型?
TypeScript 实现多层嵌套主题类型到表单类型的转换
需求说明
需要将多层不规则嵌套的Theme接口转换为对应的表单主题对象ThemeForm,类型映射规则如下:
Color1类型映射为FormField<Color2>string类型映射为FormField<boolean>number类型映射为FormField<number>- 嵌套的对象结构需保持层级,递归处理内部字段
解决方案:递归条件类型
通过递归条件类型可以完美处理嵌套结构的类型转换。核心是定义一个泛型类型,自动判断当前字段是基础类型(直接映射)还是对象类型(递归处理)。
完整代码实现
首先给出所有基础类型定义:
type Color1 = string & { __brand: "color1" } type Color2 = string & { __brand: "color2" } type FormTypes = string | number | boolean | undefined; interface FormField<F extends FormTypes> { value: F; error: boolean; errorMsg: string; } interface Theme { colors: { primary: Color1; }; border: { radius: number; }; fonts: { main: string; }; components: { container: { padding: number }, radioCheckbox: { active: Color1; }; }; }
然后定义递归类型转换器:
// 递归处理嵌套类型的转换器 type ThemeToForm<T> = { [K in keyof T]: T[K] extends Color1 ? FormField<Color2> : T[K] extends string ? FormField<boolean> : T[K] extends number ? FormField<number> : T[K] extends object ? ThemeToForm<T[K]> : T[K] };
最后生成目标类型:
// 生成符合要求的ThemeForm类型 type ThemeForm = ThemeToForm<Theme>;
类型转换逻辑说明
- 遍历输入类型
T的所有属性键K - 对每个属性的类型
T[K]依次匹配规则:- 优先匹配
Color1类型,直接转换为FormField<Color2> - 匹配
string类型,转换为FormField<boolean> - 匹配
number类型,转换为FormField<number> - 若为对象类型(排除基础类型的包装对象),则递归调用
ThemeToForm处理嵌套结构 - 其他类型保持原类型(可根据需求扩展规则)
- 优先匹配
验证结果
生成的ThemeForm类型与目标结构完全一致:
// 等价于用户给出的目标接口 interface ThemeForm { colors: { primary: FormField<Color2>; }; border: { radius: FormField<number>; }; fonts: { main: FormField<boolean>; }; components: { container: { padding: FormField<number> }, radioCheckbox: { active: FormField<Color2>; }; }; }
内容的提问来源于stack exchange,提问作者psygo
相关产品推荐
相关产品推荐

