如何以类型安全的方式替换setTimeout方法?
解决TypeScript中替换setTimeout的类型不匹配问题
报错原因是globalThis.setTimeout在Node.js环境下的类型不仅包含函数调用签名,还自带promisify静态属性,你自定义的函数只实现了调用逻辑,缺少该属性导致类型校验失败。以下是不用any/unknown的解决方法:
方法1:完整匹配类型(推荐)
通过Object.assign把原setTimeout的promisify属性附加到自定义函数上,同时保留原函数的参数兼容性和返回值类型:
let defaultTimeout: typeof globalThis.setTimeout; beforeEach(() => { defaultTimeout = global.setTimeout; globalThis.setTimeout = Object.assign( (callback: TimerHandler, ...args: any[]) => { // 固定延迟时间为500,同时传递原函数的额外参数 return defaultTimeout(callback, 500, ...args); }, { promisify: defaultTimeout.promisify } ); });
方法2:精确类型断言
如果测试场景不需要用到promisify,可以用精确的类型断言跳过属性校验,比any更符合类型规范:
let defaultTimeout: typeof globalThis.setTimeout; beforeEach(() => { defaultTimeout = global.setTimeout; globalThis.setTimeout = ((callback: TimerHandler) => { return defaultTimeout(callback, 500); }) as typeof globalThis.setTimeout; });
额外建议:使用测试框架的Fake Timers
如果是在Jest等测试框架中,直接用框架自带的fake timers更简洁,不需要手动替换setTimeout:
beforeEach(() => { jest.useFakeTimers(); }); // 在测试中快速执行所有定时器 test('example', () => { // 执行包含定时器的代码 jest.runAllTimers(); // 断言结果 }); afterEach(() => { jest.useRealTimers(); });
内容的提问来源于stack exchange,提问作者Michael Wiles
相关产品推荐
相关产品推荐

