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

TypeScript类方法校验方法实现问题:参数匹配与类内调用

解决方案

问题分析

  1. 函数参数未严格校验:TypeScript默认允许参数更少的函数赋值给参数更多的函数(因JavaScript支持忽略多余参数),导致原代码无法检测参数个数不匹配的错误。
  2. 类内部调用失败:原代码使用this作为泛型约束目标,构造函数中this的类型未完全确定,引发泛型推断异常。

修正后的代码

// 提取类中所有方法名的工具类型
type ClassMethodNames<T> = keyof {
  [K in keyof T as T[K] extends (...args: any[]) => any ? K : never]: T[K]
};

// 强制函数参数个数、类型与返回值完全匹配的工具类型
type StrictFunctionMatch<T extends (...args: any[]) => any> = 
  <U extends (...args: any[]) => any>(
    U extends (...args: Parameters<T>) => ReturnType<T> 
    ? Parameters<U>['length'] extends Parameters<T>['length'] 
      ? U 
      : never 
    : never
  );

class M {
  val!: string;
  fnDat!: (str: string, num: number) => Date;
  fnNum!: (num: number) => number;
  fnStr!: (str: string) => string;

  // 修正泛型约束,基于类原型确保类型推断准确
  cheker<MethodName extends ClassMethodNames<typeof M.prototype>>(
    methodName: MethodName,
    method: StrictFunctionMatch<typeof M.prototype[MethodName]>
  ) {
    console.log(methodName, method);
  }

  constructor() {
    // 合法调用,无类型错误
    this.cheker("fnDat", (str: string, num: number) => new Date());
    this.cheker("fnNum", (num: number) => num);
    this.cheker("fnStr", (str: string) => str);

    // 以下调用均会触发类型错误,符合预期
    this.cheker("val", () => {}); // 错误:val不是方法
    this.cheker("fnDat", () => new Date()); // 错误:参数个数不匹配
    this.cheker("fnDat", (str: string, num: number) => null); // 错误:返回类型应为Date
    this.cheker("fnNum", (num: number) => ""); // 错误:返回类型应为number
    this.cheker("fnStr", (str: string) => 10); // 错误:返回类型应为string
    this.cheker("fnNotExistsInM", () => {}); // 错误:方法名不存在
  }
}

const m = new M();

// 外部合法调用
m.cheker("fnDat", (str: string, num: number) => new Date());
m.cheker("fnNum", (num: number) => num);
m.cheker("fnStr", (str: string) => str);

// 外部错误调用(均触发类型错误)
m.cheker("val", () => {});
m.cheker("fnDat", () => new Date());
m.cheker("fnDat", (str: string, num: number) => null);
m.cheker("fnNum", (num: number) => "");
m.cheker("fnStr", (str: string) => 10);
m.cheker("fnNotExistsInM", () => {});

关键改动说明

  • ClassMethodNames优化:使用映射类型的as子句直接过滤出方法名,类型推导更简洁准确。
  • StrictFunctionMatch工具类型:通过检查参数元组长度、参数类型和返回值类型,强制传入函数与目标方法完全匹配,解决参数个数不校验的问题。
  • 泛型约束调整:将泛型约束改为基于typeof M.prototype,确保构造函数内this.cheker的类型推断正常工作。

内容的提问来源于stack exchange,提问作者Daniel de Andrade Varela

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 17:04:51