TypeScript如何实现对象动态键名匹配对应值类型
可行实现方案
可以完全实现需求,同时避免多层条件类型嵌套,做到规则可灵活扩展。
核心思路是把路径模式-返回类型的映射规则和匹配逻辑拆分:规则单独维护,匹配逻辑通用复用,新增规则不需要修改匹配逻辑。
具体实现
1. 定义规则表
用元组存储规则,元组每一项是[路径模式, 匹配后返回的类型],元组顺序就是匹配优先级(越靠前优先级越高,匹配到即返回,不会继续往后匹配)。
路径模式里的动态段直接用TS模板字面量的类型占位:原来的[number]替换为${number},[string]替换为${string}即可。
// 所有匹配规则都在这里维护,新增规则直接往数组里加就行 type DynamicObjRules = [ [`some/${number}`, number], [`some/${string}`, string], // 新增规则示例: // [`api/user/${number}`, { id: number; name: string }], // [`api/post/${string}/createTime`, Date], ];
2. 实现通用递归匹配类型
按规则表的顺序逐个匹配传入的路径,匹配到对应模式就返回绑定的类型,所有规则都不匹配返回never:
type MatchRule< T extends string, Rules extends [string, unknown][] > = Rules extends [ [infer Pattern extends string, infer Value], ...infer Rest extends [string, unknown][] ] ? T extends Pattern ? Value : MatchRule<T, Rest> : never;
3. 定义最终的DynamicObj类型
type DynamicObj<T extends string> = MatchRule<T, DynamicObjRules>;
效果验证
type a = DynamicObj<'some/1'>; // 正确推导为number type b = DynamicObj<'some/sdfs'>; // 正确推导为string
如果后续需要新增匹配规则,只需要在DynamicObjRules元组里按优先级添加新的[模式, 类型]条目即可,完全不需要修改匹配逻辑,不会出现多层条件嵌套的问题。
优先级说明:因为
${number}类型的路径也满足${string}的匹配规则,我们把数字段的规则放在元组更靠前的位置,就会优先匹配到number类型,不会出现返回number | string联合类型的问题。
内容的提问来源于stack exchange,提问作者Angus
相关产品推荐
相关产品推荐

