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:区分一元/二元类型,使用区分联合类型
如果需要严格区分操作符类型(确保调用时参数数量正确),可以拆分类型并结合区分联合类型:
- 先定义基础函数类型:
type UnaryCountFn = (operand: number) => number; type BinaryCountFn = (left: number, right: number) => number;
- 定义区分操作符的实体类型:
// 一元操作符实体类型 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;
- 使用时通过
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
相关产品推荐
相关产品推荐

