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

TypeScript中如何为Operators的count函数定义动态参数类型?

操作符实体的函数类型定义问题

问题背景

在定义操作符实体时,部分操作符的count函数是一元函数(仅接收1个number参数),部分是二元函数(接收2个number参数)。若将count的类型定义为:

type CountFunction = (operand1: number, operand2?: number) => number;

会导致二元函数(如(left, right) => left + right)出现类型错误——因为该二元函数要求第二个参数必须存在,但CountFunction允许第二个参数为undefined,类型不兼容。

解决方案

方案1:使用函数重载定义兼容类型

通过函数重载可以同时支持一元和二元函数的赋值与调用,无需拆分类型:

type CountFunction = {
  // 一元函数签名
  (operand: number): number;
  // 二元函数签名
  (left: number, right: number): number;
};

此类型既可以接收Math.sin这类一元函数,也能接收(a,b)=>a+b这类二元函数,TypeScript会自动匹配对应的函数签名。

方案2:区分一元/二元类型,使用区分联合类型

如果需要严格区分操作符类型(确保调用时参数数量正确),可以拆分类型并结合区分联合类型:

  1. 先定义基础函数类型:
type UnaryCountFn = (operand: number) => number;
type BinaryCountFn = (left: number, right: number) => number;
  1. 定义区分操作符的实体类型:
// 一元操作符实体类型
type UnaryOperator = {
  textForInput: string;
  onClick: () => void; // 请根据实际onClick类型调整
  type: typeof UNARY_OPERATOR_TYPE;
  innerHtml: string;
  level: number;
  count: UnaryCountFn;
  className: string;
};

// 二元操作符实体类型
type BinaryOperator = {
  textForInput: string;
  onClick: () => void;
  type: typeof BINARY_OPERATOR_TYPE;
  innerHtml: string;
  level: number;
  count: BinaryCountFn;
  className: string;
};

// 联合操作符类型
type OperatorValue = UnaryOperator | BinaryOperator;
  1. 使用时通过type字段做类型窄化:
function runOperator(op: OperatorValue, ...args: number[]) {
  if (op.type === UNARY_OPERATOR_TYPE) {
    // TypeScript自动推断op.count为UnaryCountFn
    return op.count(args[0]);
  } else {
    // TypeScript自动推断op.count为BinaryCountFn
    return op.count(args[0], args[1]);
  }
}

原定义报错原因

二元函数(left, right) => left + right的类型是(a: number, b: number) => number,它要求必须传入两个参数;而(operand1: number, operand2?: number) => number允许只传一个参数,此时二元函数会接收到undefined作为第二个参数,存在运行时风险,因此TypeScript会抛出类型错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 13:55:14