如何修复TypeScript中invokeLater函数的ReturnType类型约束错误?
解决TypeScript中ReturnType<T[M]>的约束错误
问题原因
你写的invokeLater函数里,泛型M只被约束为keyof T,这意味着M可以指向T的任何属性——包括那些值不是函数的属性(比如字符串、数字类型的属性)。而ReturnType<T[M]>要求传入的类型必须是函数类型,所以TypeScript会抛出Type 'T[M]' does not satisfy the constraint '(...args: any[]) => any'的错误。
解决方案
我们需要收紧泛型约束,确保M只能指向T中那些值为函数类型的属性。这里有两种清晰的实现方式:
方式1:直接在泛型约束中过滤
修改泛型参数的约束,只允许M对应T里的函数属性:
function invokeLater<T extends object, M extends keyof T & (T[M] extends (...args: any[]) => any ? M : never)>( context: T, method?: M ): ((...params: Parameters<T[M]>) => ReturnType<T[M]>) { // 示例实现(可根据你的需求调整) return (...params) => { if (!method) throw new Error("Method is required"); return (context[method] as (...args: any[]) => any)(...params); }; }
方式2:用辅助类型提取函数属性键
先定义一个辅助类型FunctionKeys,专门提取对象中值为函数的属性名,再用它约束M:
// 辅助类型:提取T中所有值为函数的属性键 type FunctionKeys<T> = { [K in keyof T]: T[K] extends (...args: any[]) => any ? K : never }[keyof T]; function invokeLater<T extends object, M extends FunctionKeys<T>>( context: T, method?: M ): ((...params: Parameters<T[M]>) => ReturnType<T[M]>) { return (...params) => { if (!method) throw new Error("Method is required"); return context[method](...params); }; }
额外优化
上面的代码还加入了Parameters<T[M]>来约束返回函数的参数类型,让返回的函数和原方法的参数类型完全匹配,进一步提升类型安全性。
内容的提问来源于stack exchange,提问作者Masoud Zohrabi
相关产品推荐
相关产品推荐

