在TypeScript中将类型测试集成到单元测试的实践与需求
TypeScript类型测试工具需求
我在依赖窄类型的TypeScript项目中,常使用@type-challenges/utils工具编写「类型测试」,示例代码如下:
describe("example of a type test", () => { it("SetRemoval<TSet, TRemoval>", () => { type Set1 = ["foo", "bar", "baz"]; type Set2 = ["bat-shit-crazy", "never mind"]; type T1 = SetRemoval<Set1, "foo">; type T2 = SetRemoval<Set1, ["foo"]>; type T3 = SetRemoval<[...Set1, ...Set2], ["foo", "never mind"]>; type cases = [ Expect<Equal<T1, readonly ["bar", "baz"]>>, Expect<Equal<T2, readonly ["bar", "baz"]>>, Expect<Equal<T3, readonly ["bar", "baz", "bat-shit-crazy"]>>, ]; const cases: cases = [ true, true, true ]; }); });
这类类型测试的优势在于:
- 支持类型错误高亮的编辑器可即时显示类型问题;
- 可通过
tsc检查测试文件确保无类型错误。
我目前主要使用Vitest做单元测试,也曾用过Jest、Mocha和UVU,但这些测试框架要么完全忽略类型错误,要么因文件中存在类型错误就拒绝运行所有测试,均不理想。现寻求一款已有的工具,支持仅测试代码块的类型有效性,而非整个文件。
推荐工具
1. tsd
专门针对TypeScript类型测试的工具,支持单独测试类型断言块,不会因为文件中其他代码的类型错误中断测试。你可以编写独立的类型测试文件,或者在现有测试中标记类型测试逻辑,它只会检查指定的类型断言部分是否符合预期。
使用示例:
import { expectType } from 'tsd'; import { SetRemoval } from './your-module'; type Set1 = ["foo", "bar", "baz"]; type Set2 = ["bat-shit-crazy", "never mind"]; type T1 = SetRemoval<Set1, "foo">; expectType<readonly ["bar", "baz"]>({} as T1); type T2 = SetRemoval<Set1, ["foo"]>; expectType<readonly ["bar", "baz"]>({} as T2); type T3 = SetRemoval<[...Set1, ...Set2], ["foo", "never mind"]>; expectType<readonly ["bar", "baz", "bat-shit-crazy"]>({} as T3);
2. type-testing
轻量级类型测试工具,和@type-challenges/utils的风格兼容,可直接复用现有的Expect和Equal断言写法。只需将测试用例用它提供的标记包裹,工具就会单独验证这些代码块的类型有效性,不会受文件其他部分类型错误的影响。
3. ts-expect
可在现有测试文件中插入类型断言语句,不影响运行时测试,仅在类型检查阶段验证断言是否正确。你可以通过配置tsconfig.json或工具参数,让它只关注标记的类型测试代码,忽略文件其他部分的类型错误(若有需要)。
使用示例:
import { expectType } from 'ts-expect'; expectType<Equal<SetRemoval<["foo", "bar"], "foo"], ["bar"]>>();
内容的提问来源于stack exchange,提问作者ken
相关产品推荐
相关产品推荐

