TypeScript如何创建同嵌套结构但所有属性值均为string的类型
问题背景
现有如下TypeScript类型定义:
interface SomeType { prop1: number, prop2: string, prop3: SomeEnum, prop4: { nestedProp1: number } } enum SomeEnum { value1, value2, value3, }
需要生成一个嵌套结构与上述类型完全一致的新类型,要求新类型内所有属性值的类型均为string(目标类型可按需替换)。
现有可参考的实现方案仅能部分满足需求,依赖所有叶子节点值原本为统一类型的前提;但实际场景中存在大量不同枚举作为属性值的情况,如果通过条件类型穷举所有可能值来替换类型判断逻辑,方案会非常脆弱、可维护性差。
实现方案
直接实现一个递归映射的通用工具类型即可,无需穷举任何原始类型、枚举类型,自动识别嵌套对象结构做递归处理,所有叶子节点统一替换为指定类型,完全规避原有方案的缺陷。
工具类型定义
基础版(适配纯对象嵌套场景)
type DeepReplace<T, TargetType> = { [K in keyof T]: T[K] extends object ? DeepReplace<T[K], TargetType> : TargetType }
增强版(兼容对象+数组嵌套场景)
如果业务场景中存在数组类型的属性,可以使用兼容数组判断的版本:
type DeepReplace<T, TargetType> = { [K in keyof T]: T[K] extends Array<infer Item> ? Array<DeepReplace<Item, TargetType>> : T[K] extends object ? DeepReplace<T[K], TargetType> : TargetType }
使用方式
传入原始类型、需要替换的目标类型即可生成符合要求的新类型,以所有属性替换为string为例:
type StringifiedSomeType = DeepReplace<SomeType, string>
生成的StringifiedSomeType结构与原类型完全对齐,所有叶子属性均被替换为string:
prop1: string(原类型为number,自动替换)prop2: string(原类型为string,自动替换)prop3: string(原类型为枚举,枚举作为类型时是原始值的联合类型,会被识别为叶子节点自动替换,无需单独适配所有枚举)prop4: { nestedProp1: string }(嵌套结构自动递归处理)
该方案不需要维护任何原始类型、枚举类型的判断白名单,后续新增任意类型的叶子属性(布尔值、新增枚举、symbol等)都会被自动替换为目标类型,可维护性远高于穷举类型的实现。
内容的提问来源于stack exchange,提问作者MattTreichel
相关产品推荐
相关产品推荐

