TypeScript类型层级编程:如何泛型替换指定类型实例?
通用TypeScript类型层级替换方案
要实现无需预设数组、Map等构造器的类型层级替换,可以利用TypeScript的条件类型、递归遍历和infer关键字,编写一个能自动处理原始类型、对象(含数组/元组)、函数的通用工具类型。
核心实现
type ReplaceType<T, Find, Replace> = // 匹配目标类型直接替换 T extends Find ? Replace : // 处理函数:递归替换参数和返回值类型 T extends (...args: infer Args) => infer Ret ? (...args: ReplaceType<Args, Find, Replace>) => ReplaceType<Ret, Find, Replace> : // 处理对象类型(包括普通对象、数组、元组等):遍历所有属性递归替换 T extends object ? { [K in keyof T]: ReplaceType<T[K], Find, Replace> } : // 原始类型直接返回 T;
使用示例
假设我们有如下嵌套类型,需要把所有"placeholder"替换为"value":
// 原始类型 type Example = { basic: "placeholder"; nested: { child: "placeholder"; list: "placeholder"[]; }; func: (input: "placeholder") => "placeholder"; }; // 替换后的结果类型 type Result = ReplaceType<Example, "placeholder", "value">;
Result的最终类型等价于:
type Result = { basic: "value"; nested: { child: "value"; list: "value"[]; }; func: (input: "value") => "value"; };
方案说明
- 原始类型处理:直接判断当前类型是否为目标
Find类型,是则替换为Replace。 - 函数类型处理:通过
infer提取参数列表和返回值类型,递归替换其中的目标类型。 - 对象类型处理:利用
keyof遍历对象的所有属性(包括数组的number索引、元组的字面量索引),对每个属性类型递归执行替换。
局限性说明
对于Map、Set这类内置泛型容器,该方案会替换其方法中涉及的目标类型(比如Map.get()的返回值),但不会直接修改容器的泛型参数声明。如果需要严格替换泛型参数类型,仍需针对特定容器类型添加额外的条件分支,但这会涉及预设构造器——这是当前TypeScript类型系统的限制,因为无法动态提取任意泛型类型的参数列表。
内容的提问来源于stack exchange,提问作者sh03
相关产品推荐
相关产品推荐

