类型测试
Vitest 允许你使用 expectTypeOf
或 assertType
语法编写类型测试。默认情况下,*.test-d.ts
文件中的所有测试都会被视为类型测试,但你可以使用 typecheck.include
配置选项来修改此行为。
在底层,Vitest 会调用 tsc
或 vue-tsc
,具体取决于你的配置,并解析其结果。如果 Vitest 检测到源代码中的类型错误,它会将其打印出来。你可以使用 typecheck.ignoreSourceErrors
配置选项来禁用此功能。
请注意,Vitest 不会运行或编译这些文件,它们仅由编译器进行静态分析。因此,你不能使用动态测试名称,以及 test.each
、test.runIf
、test.skipIf
、test.concurrent
等 API。但是,你可以使用其他 API,例如 test
、describe
、.only
、.skip
和 .todo
。
类型检查同样支持 CLI 标志,例如 --allowOnly
和 -t
。
import { assertType, expectTypeOf } from 'vitest';
import { mount } from './mount.js';
test('my types work properly', () => {
expectTypeOf(mount).toBeFunction();
expectTypeOf(mount).parameter(0).toMatchTypeOf<{ name: string }>();
// @ts-expect-error name is a string
assertType(mount({ name: 42 }));
});
测试文件中触发的任何类型错误都会被视为测试失败,因此你可以使用任何你想要的类型技巧来测试项目的类型。
你可以在 API 部分 中查看可用的匹配器列表。
读取错误
如果你正在使用 expectTypeOf
API,你可能会遇到难以理解的错误或意外情况:
expectTypeOf(1).toEqualTypeOf<string>();
// ^^^^^^^^^^^^^^^^^^^^^^
// index-c3943160.d.ts(90, 20): Arguments for the rest parameter 'MISMATCH' were not provided.
这是由于 expect-type
处理类型错误的方式导致的。
遗憾的是,TypeScript 不提供未经处理的类型元数据,因此我们目前无法提供有用的错误消息。但是,TypeScript 项目中正在进行相关工作来解决这个问题。如果你需要更友好的错误信息,请向 TypeScript 团队反馈,要求他们关注上述 PR。
如果你觉得使用 expectTypeOf
API 难以定位错误,你可以随时使用更简单的 assertType
API:
const answer = 42;
assertType<number>(answer);
// @ts-expect-error answer is not a string
assertType<string>(answer);
TIP
当使用 @ts-expect-error
语法时,你可能需要确保没有拼写错误。你可以在 test.include
配置选项中包含类型文件来实现这一点,这样 Vitest 也会实际 运行 这些测试,并因 ReferenceError
而失败。
以下代码会通过,因为它期望一个错误,但单词 ‘answer’ 拼写错误,因此这是一个假阳性错误:
// @ts-expect-error answer is not a string
assertType<string>(answr); //
运行类型检查
将以下命令添加到 package.json
的 scripts
部分:
{
"scripts": {
"typecheck": "vitest typecheck"
}
}
现在可以运行类型检查:
# npm
npm run typecheck
# yarn
yarn typecheck
# pnpm
pnpm run typecheck
Vitest 使用 tsc --noEmit
或 vue-tsc --noEmit
,具体取决于你的配置,因此你可以从构建流水线中移除这些脚本。