调用接收泛型Handler参数的方法时如何为每个Handler指定泛型T
原有实现的问题
你最初的Handler类型把泛型参数定义在函数签名上,这代表任意一个符合Handler类型的函数都要支持任意类型的T,而非绑定某个固定的T,这和你需要的「每个handler对应自己的固定T类型」的需求正好相反。
你修改的方案的合理性和问题
你调整后的实现思路是对的,把泛型参数移到了类型本身上面,但存在两个问题:
- 泛型参数声明语法错误:
Handler<T | any>是无效写法,如果要给T设默认值应该写为Handler<T = any>,同时你的类型定义中漏了参数列表的闭合括号,修正后如下:
export type Handler<T = any> = (input: Input, output: Output<T>) => Promise<void>;
- 用类型断言的方式虽然能获得你需要的类型提示,但属于「手动告诉TS类型是什么」,会跳过自动类型校验:如果你的函数实现和你断言的
Handler<string>类型不匹配,TS不会主动抛出错误,存在类型安全隐患。
更安全的推荐方案
把MyMethod改造为泛型方法,让TS自动推导每个handler对应的T类型,不需要手动断言也能获得完整的类型校验:
// 首先修正Handler的泛型定义 export type Handler<T> = (input: Input, output: Output<T>) => Promise<void>; // MyMethod泛型化,接收映射类型参数,自动匹配每个key对应的T类型 function MyMethod<T extends Record<string, unknown>>(handlers: { [K in keyof T]: Handler<T[K]> }) { // 方法内部实现 }
调用时TS会自动识别每个handler的T类型,也可以显式指定类型映射获得更严谨的校验:
// 自动推导模式,one对应T=string,two对应T=number MyMethod({ one: async (input, output) => { // 这里output会自动被推断为Output<string>类型 }, two: async (input, output) => { // 这里output会自动被推断为Output<number>类型 } }); // 显式指定类型映射,严格校验传入的handler MyMethod<{ one: string; two: number }>({ one: async (input, output) => {/* 逻辑 */}, two: async (input, output) => {/* 逻辑 */} });
内容的提问来源于stack exchange,提问作者Scott Perham
相关产品推荐
相关产品推荐

