如何为TypeScript的fetchThings函数实现多参数关联类型约束
TypeScript fetchThings 关联类型约束实现方案
错误原因
你遇到的编译报错本质是混淆了索引签名和映射类型的语法规则:
- 索引签名语法
[key: 类型]: 值类型中的类型仅支持string/number/symbol三类固定基础类型,不支持传入泛型参数 - 要实现键为泛型P的对象类型,需要使用映射类型语法
{ [K in P]: CustomisationProvider },也可以直接使用TypeScript内置的等价工具类型Record<P, CustomisationProvider>
另外原有代码中的for...in遍历数组的写法存在运行时错误:for...in会遍历得到数组的索引字符串,而非数组内的元素值,需要改为for...of遍历。
正确实现
调整泛型声明顺序和约束即可同时满足所有规则:
sources中的元素同时是services和ids的键ids对应键的值类型为string
abstract class CustomisationProvider { abstract fetch(id: string): any; } function fetchThings<P extends string>( sources: P[], // 约束ids的键为P,对应值必须为string,若需要允许ids存在额外键可改为 Record<P, string> & Record<string, any> ids: Record<P, string>, // 约束services的键为P,对应值为CustomisationProvider services: Record<P, CustomisationProvider> ){ for(const s of sources){ services[s].fetch(ids[s]); } }
效果验证
合法调用示例
fetchThings( ['user', 'goods'], { user: '1001', goods: '2001' }, { user: { fetch: (id) => console.log('fetch user', id) }, goods: { fetch: (id) => console.log('fetch goods', id) } } )
非法调用会触发类型报错
- 若
ids对应键的值不是string类型 - 若
services缺少sources中存在的键 - 若
sources出现ids/services中不存在的键
内容的提问来源于stack exchange,提问作者Bob
相关产品推荐
相关产品推荐

