You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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>结果为never
  • ReturnType<never>最终是unknown,无法实现类型约束的效果

优化建议

如果希望更严谨地约束C的类型(确保所有属性都是方法),可以将StringKeyedObject替换为:

interface MethodContainer {
  [key: string]: (...args: any[]) => any;
}

然后Handler类改为class Handler<C extends MethodContainer>,这样能避免传入非方法类型的属性。

内容的提问来源于stack exchange,提问作者Kleywalker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 11:42:46