如何在TypeScript中动态创建并暴露同名重载函数?
实现JavaScript中基于参数类型的函数重载
JavaScript本身不支持传统意义上的函数重载(同名函数会直接覆盖),但你可以通过参数类型判断+分发逻辑来实现类似效果。核心思路是为同名函数创建一个统一的入口,内部根据传入参数的类型匹配对应的处理逻辑。
具体实现步骤
- 按函数名称分组,存储不同参数类型的处理逻辑
先把输入的函数定义按名称归类,每个名称下保存参数类型组合与对应函数的映射。 - 创建入口函数,实现类型匹配与分发
为每个函数名称生成一个入口函数,该函数会检查传入参数的类型,找到匹配的处理逻辑后执行,若没有匹配项可抛出错误或做默认处理。
完整代码示例
const input = [ { name: 'mul', paramTypes: { par1: 'number', par2: 'number' } }, { name: 'add', paramTypes: { par1: 'number', par2: 'number' } }, { name: 'add', paramTypes: { par1: 'string', par2: 'string' } } ]; let functionsToExpose = {}; // 第一步:按函数名称分组,构建类型-处理函数的映射 const functionMap = {}; input.forEach(funcDef => { const { name, paramTypes } = funcDef; // 将参数类型转为有序字符串,作为匹配键 const typeKey = Object.values(paramTypes).join(','); if (!functionMap[name]) { functionMap[name] = {}; } // 绑定对应类型的处理逻辑 functionMap[name][typeKey] = (...args) => { switch(typeKey) { case 'number,number': return name === 'mul' ? args[0] * args[1] : args[0] + args[1]; case 'string,string': return args[0] + args[1]; default: throw new Error(`Unsupported type combination: ${typeKey}`); } }; }); // 第二步:创建入口函数,处理类型匹配与分发 Object.keys(functionMap).forEach(name => { functionsToExpose[name] = (...args) => { // 获取传入参数的类型字符串 const argTypes = args.map(arg => typeof arg).join(','); const handler = functionMap[name][argTypes]; if (handler) { return handler(...args); } throw new Error(`No matching ${name} function for types: ${argTypes}`); }; }); // 测试验证 console.log(functionsToExpose.add(1, 2)); // 3(数字加法) console.log(functionsToExpose.add('hello', ' world')); // 'hello world'(字符串拼接) console.log(functionsToExpose.mul(3, 4)); // 12(乘法) // functionsToExpose.add(1, '2'); // 抛出错误:无匹配类型
关键点说明
- 类型匹配精度:使用
typeof足以应对基础类型场景,如果需要处理引用类型(如对象、数组),可以改用Object.prototype.toString.call(arg)获取更精确的类型标识(如[object Array])。 - 参数顺序敏感:类型匹配严格遵循参数顺序,
[number, string]和[string, number]会被视为不同的类型组合,符合函数重载的预期。 - 扩展性:后续新增类型组合的函数时,只需在
input中添加定义,核心分发逻辑无需修改。
内容的提问来源于stack exchange,提问作者Nikos Iliakis
相关产品推荐
相关产品推荐

