如何在TypeScript中实现类似C++模板的多类型同名函数
TypeScript 实现同名函数适配不同参数类型方案
TypeScript 可以实现和你给出的C++模板示例完全一致的效果,核心依赖函数重载+泛型能力,需要注意TypeScript的类型系统仅在编译阶段生效,最终运行时需要补充简单的类型判断逻辑执行对应分支。
注意差异
TypeScript 和C++的类型系统存在两个基础差异,实现时需要适配:
- TypeScript 没有独立的
int、double原始类型,所有数值统一为number类型,可以通过数值特征对齐C++的两个数值分支 - TypeScript 泛型属于编译时语法,编译后会被擦除,不会像C++模板一样生成不同的函数实例,运行时无法直接获取传入的泛型参数;如果只需要根据参数类型自动适配,直接判断参数类型即可,需要严格匹配显式泛型分支时可以补充运行时标记
基础实现(自动根据参数类型适配)
这是TS最常用的写法,不需要显式指定类型参数,编译时会自动校验参数类型,运行时自动匹配对应分支:
// 重载签名:定义不同参数类型对应的调用类型约束 function print(x: number): void; function print(x: string): void; // 函数统一实现 function print(x: number | string): void { if (typeof x === 'string') { console.log(`IS STRING: ${x}`); return; } // 数值分支区分int/double if (Number.isInteger(x)) { console.log(`IS INT: ${x}`); } else { console.log(`IS DOUBLE: ${x}`); } } // 调用示例 print(2); print(8.0); print("HA");
对齐C++显式指定类型参数的写法
如果你需要和C++完全一致的print<类型>()显式指定类型的调用形式,可以补充泛型签名和类型别名:
// 模拟C++的int、double类型别名 type int = number; type double = number; // 泛型重载签名 function print<T extends int>(x: T): void; function print<T extends double>(x: T): void; function print<T extends string>(x: T): void; function print(x: number | string): void { if (typeof x === 'string') { console.log(`IS STRING: ${x}`); return; } // 编译阶段TS会校验传入参数和泛型类型是否匹配 // 运行时按参数特征判断分支 if (Number.isInteger(x)) { console.log(`IS INT: ${x}`); } else { console.log(`IS DOUBLE: ${x}`); } } // 和C++完全一致的调用方式 print<int>(2); print<double>(8.0); print<string>("HA");
运行结果
上述两种写法的输出都和C++示例完全一致:
IS INT: 2
IS DOUBLE: 8
IS STRING: HA
内容的提问来源于stack exchange,提问作者GFoniX
相关产品推荐
相关产品推荐

