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

如何阻止TypeScript接受签名相同但类型不同的函数作为参数

解决思路

TypeScript 默认使用结构类型系统做类型校验:只要两个类型的内部结构完全一致,就会判定二者兼容。你示例中type A和type B的函数签名结构完全相同,因此TS会认为二者可以互相替换。

要阻止b传入C,需要给两个函数类型添加独有标识,破坏结构一致性,模拟名义类型的校验效果。

具体实现方案

给每个函数类型追加一个唯一的类型层面标记即可,标记不会影响运行时逻辑:

// 用unique symbol保证标记全局唯一,不会和其他属性冲突
const AFuncTag = Symbol('AFunc');
const BFuncTag = Symbol('BFunc');

// 给函数类型交叉上独有标记属性
type A = ((a: string) => void) & { [AFuncTag]: true };
type B = ((b: string) => void) & { [BFuncTag]: true };

// 定义函数时用类型断言打上对应标记,运行时不会真的添加属性
const a = ((a: string) => {}) as A;
const b = ((b: string) => {}) as B;

function C(func: A) {
    // ...
}

C(a); // 类型校验通过
C(b); // 直接报错:类型“B”的参数不能赋给类型“A”的参数,属性[AFuncTag]在类型B中不存在

也可以封装通用的名义函数类型工具,简化重复定义:

type NominalFunction<Param, Return, Tag extends string> = 
  ((p: Param) => Return) & { __funcTag: Tag };

// 直接传入不同Tag即可生成互不兼容的同签名函数类型
type A = NominalFunction<string, void, 'A'>;
type B = NominalFunction<string, void, 'B'>;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 17:45:04