Typescript如何用模板字面量推断实现带/不带$后缀的实体子属性类型
解决方案
类型定义
直接使用以下单类型定义即可满足需求,无需拆分多个子类型:
type ChildAttribute<E> = { [K in keyof E]: K extends `${infer Att}$` ? Att | K : never }[keyof E]
效果验证
针对你给出的测试场景,校验结果完全符合预期:
class Pet { name: string; owner$: any; } // 合法取值(校验通过) const att1: ChildAttribute<Pet> = 'owner$'; const att2: ChildAttribute<Pet> = 'owner'; // 非法取值(均触发类型报错) const att3: ChildAttribute<Pet> = 'name'; // 非子属性无后缀名,拦截成功 const att4: ChildAttribute<Pet> = 'previousOwner$'; // 不存在的子属性,拦截成功
原写法失效原因
你之前的实现是将keyof E的属性名联合类型作为整体做条件判断,没有遍历每个属性逐一匹配规则,只要实体存在任意一个不带$后缀的属性,整个条件判断就会返回never,导致短名匹配失效。
上述实现通过映射类型遍历实体的每个属性,对每个属性单独做后缀匹配,符合子属性规则的会同时返回带$和不带$的两种名称,最后通过索引访问把所有符合要求的名称聚合为联合类型,完美覆盖需求。
内容的提问来源于stack exchange,提问作者Bob
相关产品推荐
相关产品推荐

