TypeScript如何精确推断映射对象内函数的参数与返回值类型
问题说明
需要实现对外暴露的myFunc接口,满足以下类型规则:
- 入参为键值任意的对象,每个属性值是接收
key、arg两个参数的函数,返回值为string或number类型 - 函数的
key参数需推断为对应属性名的字符串字面量类型 - 函数的
arg参数需推断为和自身返回值完全一致的类型
原有实现的问题是arg始终被推断为string | number联合类型,无法匹配每个函数的具体返回值类型。
实现方案
问题根源是原有泛型约束直接将MyType的第二个泛型参数固定为Value联合类型,TypeScript无法从返回值反向推导该位置的具体类型。通过自引用的映射类型约束,逐个提取每个属性函数的返回值类型关联到arg参数即可解决,完整实现代码如下:
type Value = string | number; type Handler<K extends PropertyKey, T extends Value> = (key: K, arg: T) => T; function myFunc<R extends { [K in keyof R]: Handler<K, R[K] extends Handler<any, infer T> ? T : never> }>(userObj: R) { // 此处编写内部业务逻辑 return userObj; // 替换为实际返回值逻辑 }
效果验证
使用示例代码测试,类型推断完全符合预期:
const userResult = myFunc({ foo: (key, arg) => { // key 类型为 "foo" // arg 类型为 string return "foobar"; }, bar: (key, arg) => { // key 类型为 "bar" // arg 类型为 number return 1; }, })
如果用户编写的代码中arg类型和返回值不匹配,TypeScript会直接抛出类型错误。
实现注意点:不需要额外声明
Ks extends keyof R这类中间泛型参数,直接让泛型R约束自身的映射结构,TypeScript才能正确触发同态映射的反向推断,避免arg类型退化为联合类型。
内容的提问来源于stack exchange,提问作者Shun Ueda
相关产品推荐
相关产品推荐

