如何让Vitest导出模块的导入类型为MockInstance而非原类型?
解决Vitest中
vi.mock({ spy: true })导入类型不自动转为MockInstance的问题 当用vi.mock("myFn", { spy: true })模拟模块时,导入的myFn还是原函数的类型,而非Vitest的MockInstance,手动类型断言不仅麻烦还不优雅,这里有几种更顺畅的解决方式:
方法1:通过模块重定义修正类型
直接用TypeScript的模块扩充功能,覆盖导入模块的类型定义,让myFn默认就是MockInstance类型:
import { myFn } from "myFn"; import type { MockInstance } from "vitest"; // 重定义myFn模块的导出类型 declare module "myFn" { export const myFn: MockInstance<typeof myFn>; } vi.mock("myFn", { spy: true }); // 现在直接用myFn就能调用mock相关方法,类型完全匹配 myFn.mockReturnValue("模拟返回值");
方法2:用vi.spyOn替代模块级mock
如果目标函数是模块的导出成员,直接用vi.spyOn来创建 spy,类型会自动推导为MockInstance,不用额外处理:
import * as myFnModule from "myFn"; // spyOn自动返回MockInstance类型的实例 const myFn = vi.spyOn(myFnModule, "myFn"); // 直接调用mock方法,类型无报错 myFn.mockResolvedValue("异步模拟结果");
方法3:自定义mock工厂函数
在vi.mock里传入工厂函数,显式返回包含spy的导出对象,TypeScript会自动识别正确类型:
import { myFn } from "myFn"; import { vi } from "vitest"; vi.mock("myFn", () => { // 先导入原模块的真实实现 const original = vi.importActual("myFn"); // 保留其他导出,只把myFn替换为spy return { ...original, myFn: vi.spyOn(original, "myFn") }; }); // 此时myFn的类型自动是MockInstance,无需断言 myFn.mockClear();
内容的提问来源于stack exchange,提问作者papillon
相关产品推荐
相关产品推荐

