如何在Node测试运行器中用TypeScript正确类型化mock.fn()?
使用 node:test + TypeScript 正确 Mock 函数类型的方案
针对你的场景,最优解是直接将ArgFnType作为Mock的类型参数,同时调整 mock 函数的实现使其兼容目标类型,而非放弃类型安全。以下是具体实现方式:
正确写法示例
方式1:让 mock 实现兼容目标函数类型
// file.test.ts import { mock } from 'node:test'; import type { Mock } from 'node:test'; import { fnToTest, type ArgFnType } from './file.js'; // 用下划线忽略不需要使用的参数,保证签名与 ArgFnType 匹配 const mockedArgFn: Mock<ArgFnType> = mock.fn((_arg1, _arg2) => Promise.resolve(fakeReturnValue)); fnToTest(mockedArgFn); // 无 TypeScript 错误
方式2:用类型断言快速绕开实现检查(适合临时 mock)
如果不想写冗余的参数占位符,可以用类型断言跳过实现层面的类型检查,但依然保留调用时的类型安全:
const mockedArgFn = mock.fn(() => Promise.resolve(fakeReturnValue)) as Mock<ArgFnType>; fnToTest(mockedArgFn);
方式3:让 TypeScript 自动推断类型(最简洁)
甚至不需要显式标注Mock类型,只要 mock 实现的签名兼容,TypeScript 会自动推断出正确的类型:
const mockedArgFn = mock.fn((_arg1, _arg2) => Promise.resolve(fakeReturnValue)); fnToTest(mockedArgFn); // 自动匹配 ArgFnType
为什么你的之前的方案存在问题
- 方案1(无类型参数):
Mock是泛型类型,必须传入类型参数才能正确约束类型,因此报错。 - 方案2(Mock
) :你遇到的类型不匹配,是因为 mock 实现没有接收ArgFnType要求的两个参数,而非类型参数本身错误。只要补全参数占位符即可解决。 - 方案3(Mock
) :Function类型过于宽泛,无法与ArgFnType的具体参数、返回值类型兼容,因此类型检查失败。 - 方案4(Mock<(...args: any[]) => unknown>):返回值类型
unknown无法赋值给Promise<CustomType3>,类型不兼容导致报错。 - 方案5(Mock<(...args: any[]) => any>):
any确实能绕过检查,但会丢失类型安全,还违反 lint 规则,不推荐在正式代码中使用。
内容的提问来源于stack exchange,提问作者onlywei
相关产品推荐
相关产品推荐

