Type tests

expectTypeOf asserts what a value's type is, and assertType that a value fits a type:

TypeScript
import { assertType, expectTypeOf, test } from "runtime:test";
import { parse } from "./parse.ts";

test("parse's types", () => {
  expectTypeOf(parse).parameter(0).toBeString();
  expectTypeOf(parse).returns.toEqualTypeOf<{ ok: boolean }>();
  expectTypeOf<Config>().toHaveProperty("port").toBeNumber();
  assertType<Config>({ port: 8080 });
});

TypeScript checks these assertions; at run time they do nothing. So they fail where TypeScript runs: esdev check, or esdev test --typecheck, which runs the project's tsc --noEmit before the tests and fails the run when it fails. A failing assertion names what it expected and what it found:

TEXT
error TS2739: Type 'ExpectTypeOf<{ a: number; }, true>' is missing the following
  properties from type 'TypeMismatch<{ a: string; }, { a: number; }>'
error TS2349: This expression is not callable.
  Type 'TypeCheckFailed<"a string", number>' has no call signatures.

Assertions

toEqualTypeOf<T>()Exactly T. any is not unknown, and readonly and optional properties count.
toExtend<T>()Assignable to T. (toMatchTypeOf is its older name.)
toMatchObjectType<T>()An object with at least T's properties, each exactly as T has it, nested objects likewise.
toBeString(), toBeNumber(), toBeBoolean(), toBeBigInt(), toBeSymbol(), toBeFunction(), toBeObject(), toBeArray(), toBeNull(), toBeUndefined(), toBeNullable(), toBeVoid(), toBeAny(), toBeUnknown(), toBeNever()
toBeCallableWith(...args) / toBeConstructibleWith(...args)
toHaveProperty(key)…and continues with the property's type.
.notEach of them the other way round.

Each of these continues with a part of the type: .returns, .parameters, .parameter(n), .constructorParameters, .instance, .items, .resolves, .guards, .asserts, .extract<T>() and .exclude<T>(). .branded.toEqualTypeOf<T>() compares types that differ only in how they are written, such as { a: 1 } & { b: 1 } and { a: 1; b: 1 }.

The names follow Vitest's expectTypeOf, so type tests move over with the import changed.

Last updated on
Edit this page