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

Vitest自定义expect匹配器扩展遇类型错误与跨文件失效问题

Vitest自定义匹配器类型错误与Chai冲突解决指南

一、修复类型声明错误

不要使用JestAssertion,正确扩展Vitest原生的Assertion接口,确保TypeScript能识别自定义匹配器类型:

  1. 在项目根目录创建vitest.d.ts文件,写入类型声明:
import type { Assertion, AsymmetricMatchersContaining } from 'vitest'

interface CustomMatchers<R = unknown> {
  toPassGuardArray(): R
}

declare module 'vitest' {
  interface Assertion<T = any> extends CustomMatchers<T> {}
  interface AsymmetricMatchersContaining extends CustomMatchers {}
}
  1. 确保tsconfig.json包含该类型文件:
{
  "include": ["src/**/*", "tests/**/*", "vitest.d.ts"]
}

二、解决跨文件调用的Chai冲突问题

方案1:完全禁用Chai(推荐)

在vitest.config.ts中禁用Chai全局断言,统一使用Vitest的Jest风格断言体系:

import { defineConfig } from 'vitest/config'

export default defineConfig({
  test: {
    globals: {
      chai: false
    }
  }
})

方案2:同时注册匹配器到Chai(需保留Chai时使用)

如果项目依赖Chai的其他断言功能,需将自定义匹配器同步注册到Chai的断言链:

// tests/setup-matchers.ts(匹配器定义文件)
import { expect } from 'vitest'
import chai from 'chai'

// 定义匹配器核心逻辑
const toPassGuardArray = (received: any) => {
  // 替换为你的实际校验逻辑
  const pass = Array.isArray(received) && received.every(item => /* 你的 guard 校验规则 */)
  
  return {
    pass,
    message: () => pass 
      ? `expected ${received} to fail guard array validation`
      : `expected ${received} to pass guard array validation`
  }
}

// 注册到Vitest的expect体系
expect.extend({ toPassGuardArray })

// 注册到Chai的断言链
chai.use((chaiInstance) => {
  chaiInstance.Assertion.addMethod('passGuardArray', function () {
    const result = toPassGuardArray(this._obj)
    this.assert(
      result.pass,
      result.message(),
      result.message().replace('fail', 'pass')
    )
  })
})

三、全局加载匹配器

将匹配器定义文件配置为Vitest前置脚本,确保所有测试文件都能访问到自定义匹配器:

// vitest.config.ts
export default defineConfig({
  test: {
    setupFiles: ['./tests/setup-matchers.ts']
  }
})

内容的提问来源于stack exchange,提问作者NadavT

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 09:07:03