TypeScript中如何根据第一个参数推导第二个参数的类型
解决方案
要实现send方法的第二个参数类型根据第一个参数自动推导,你需要直接基于C中对应方法的返回类型来约束arg,而不是原来错误的泛型写法。以下是修正后的代码:
interface Data { date: Date; message?: string; } interface DataB { dateB: Date; messageB?: string; } class DataResolver { public submit(): Data { return { date: new Date() }; } public submitB(): DataB { return { dateB: new Date() }; } } interface StringKeyedObject { [key: string]: any; } class Handler<C extends StringKeyedObject> { // 修正泛型逻辑:直接取C[K]方法的返回类型作为arg的类型 send<K extends keyof C & string>(eventName: K, arg: ReturnType<C[K]>) { // 方法逻辑 } } const handler = new Handler<DataResolver>(); // 正确:arg类型自动推导为Data handler.send('submit', { date: new Date(), message: 'hello' }); // 正确:arg类型自动推导为DataB handler.send('submitB', { dateB: new Date() }); // 错误:类型不匹配,会触发TS报错 handler.send('submit', null);
原写法问题分析
你之前的泛型L extends ReturnType<Extract<keyof K, object>>逻辑错误:
K是keyof C的子类型,也就是字符串字面量(比如"submit")keyof K取的是字符串类型的内置属性(如length、charAt等),和object类型无交集,因此Extract<keyof K, object>结果为neverReturnType<never>最终是unknown,无法实现类型约束的效果
优化建议
如果希望更严谨地约束C的类型(确保所有属性都是方法),可以将StringKeyedObject替换为:
interface MethodContainer { [key: string]: (...args: any[]) => any; }
然后Handler类改为class Handler<C extends MethodContainer>,这样能避免传入非方法类型的属性。
内容的提问来源于stack exchange,提问作者Kleywalker
相关产品推荐
相关产品推荐

