You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 14:52:10