如何创建支持多类型的动态可扩展typeExclude辅助函数?
解决方案
要让key参数能动态适配所有传入的类型,你可以通过泛型约束和联合类型键提取来实现,完全避免any类型的使用,同时保留完整的类型检查:
1. 优化类型定义(可选但更简洁)
先提取所有类型的公共属性,再通过交叉类型组合差异属性,让类型定义更清晰:
// 公共基础类型 type BaseType = { id: string; equipment: string }; // 各类型的差异属性 type TypeA = BaseType & { weight: string }; type TypeB = BaseType & { material: string }; type TypeC = BaseType & { width: string }; type TypeD = BaseType & { old: string }; type TypeE = BaseType & { recent: string }; type TypeF = BaseType & { broken: string }; type AllTypes = (TypeA | TypeB | TypeC | TypeD | TypeE | TypeF)[]; const items: AllTypes = [ { id: '11245', equipment: 'hammer', recent: 'yes' }, { id: '11335', equipment: 'screwdriver', material: 'metal' } ];
2. 实现泛型适配的动态函数
将typeExclude定义为泛型函数,让key被约束为当前元素类型的键,TypeScript会自动推断合法的键范围:
const typeExclude = <T extends BaseType>(key: keyof T, el: T) => { return key in el ? el[key] : undefined; };
3. 调用验证
调用函数时,TypeScript会自动检查key是否是当前元素类型的合法键,同时返回值类型也会被正确推断:
const arr = items.map(el => typeExclude('material', el) ? 'valid' : 'invalid'); console.log(arr); // 输出: ["invalid", "valid"]
额外优化:限定键为差异属性
如果你只想让key指向各类型的差异属性(排除公共的id和equipment),可以进一步约束键的类型:
// 提取所有差异属性的键 type DiffKeys = Exclude<keyof (TypeA | TypeB | TypeC | TypeD | TypeE | TypeF), keyof BaseType>; const typeExcludeDiff = <T extends BaseType>(key: DiffKeys, el: T) => { return key in el ? el[key as keyof T] : undefined; }; // 此时传入'id'会触发类型报错,符合预期 const arr2 = items.map(el => typeExcludeDiff('material', el) ? 'valid' : 'invalid');
内容的提问来源于stack exchange,提问作者Richardson
相关产品推荐
相关产品推荐

