TypeScript如何定义overwrite函数使新函数参数类型匹配原函数
TypeScript 实现overwrite函数的类型自动匹配
要让传入的newFunc参数类型自动和originalFunc保持一致,核心是用泛型捕获原函数的精确类型,再通过内置工具类型约束新函数的参数、返回值规则。
基础实现(匹配当前调用写法)
先修正原有代码里的笔误(新函数定义漏了箭头符号),类型定义和完整代码如下:
type Func = (...args: any[]) => any; function overwrite<T extends Func>( originalFunc: T, newFunc: (...args: Parameters<T>) => ReturnType<T> ) { // 这里写自定义的函数覆盖逻辑即可 } function demo(str: string, num: number) { console.log(str, num); } // 调用时TS会自动推导str为string类型、num为number类型,不需要手动标注 overwrite(demo, (str, num) => { console.log('new func', str, num); demo(str, num); });
类型规则说明
- 给
overwrite加泛型参数<T extends Func>,传入原函数demo时,TS会自动捕获T的精确类型为(str: string, num: number) => void - 用TS内置工具类型
Parameters<T>提取原函数的参数类型元组,直接约束newFunc的入参,实现类型自动对齐 - 用内置工具类型
ReturnType<T>提取原函数的返回值类型,约束newFunc的返回值,保证新旧函数返回值类型一致 - 如果传入的
newFunc参数个数、类型和原函数不匹配,TS会直接抛出类型错误。
更通用的优化实现
当前写法里新函数内部调用原函数需要硬编码原函数名,通用性差,可以调整类型定义,把原函数引用作为第一个参数传给新函数,避免硬编码问题:
function overwrite<T extends Func>( originalFunc: T, newFunc: (original: T, ...args: Parameters<T>) => ReturnType<T> ) { return function (...args: Parameters<T>): ReturnType<T> { return newFunc(originalFunc, ...args); }; } // 使用时不需要硬编码原函数名,直接通过参数拿到原函数引用 const newDemo = overwrite(demo, (original, str, num) => { console.log('new func', str, num); original(str, num); // 调用原逻辑 });
这个实现下新函数的参数类型依然会自动和原函数对齐,同时解决了原函数引用硬编码的问题,适合大多数函数拦截、重写的场景。
内容的提问来源于stack exchange,提问作者JayceLin
相关产品推荐
相关产品推荐

