如何实现TypeScript按条件深度转换对象属性类型的泛型?
实现代码
你要的DateToStrings<T>递归泛型可以直接这么写,兼容所有深层嵌套的属性、数组场景:
type DateToStrings<T> = // 匹配Date类型,替换为string T extends Date ? string // 匹配非Date的对象类型(含数组),递归遍历每个属性做转换 : T extends object ? { [K in keyof T]: DateToStrings<T[K]> } // 其他基础类型直接保留原类型 : T;
效果验证
拿你给出的Milk类做验证(注:你示例里的prince是笔误,统一修正为price):
// 你的原类型 class Milk { brandName: string; price: number; dealExpiredAt: Date; properties: { expirationDetails: { expiredAt: Date; }; }; } // 转换后的类型 type ConvertedMilk = DateToStrings<Milk>;
得到的ConvertedMilk类型和你要求的完全一致:
{ brandName: string; price: number; dealExpiredAt: string; properties: { expirationDetails: { expiredAt: string; }; }; }
扩展说明
- 上述实现默认支持数组转换,比如
DateToStrings<Date[]>会得到string[],嵌套数组也可正常识别。 - 如果你有其他不需要递归转换的内置对象类型(比如RegExp、Map、Set等),可以在条件分支里新增对应的判断直接返回原类型即可,示例:
type DateToStrings<T> = T extends Date ? string // 新增正则、Map、Set的保留逻辑 : T extends RegExp | Map<any, any> | Set<any> ? T : T extends object ? { [K in keyof T]: DateToStrings<T[K]> } : T;
第三方工具推荐
如果你不想自己维护递归类型的边界处理,可以用常用的TS工具库type-fest提供的DeepModify类型,它已经封装好了深层类型修改的通用逻辑,你只需要传入匹配替换规则即可实现同样的效果。
内容的提问来源于stack exchange,提问作者TG Person
相关产品推荐
相关产品推荐

