TS Expect: TypeScript Compile-Time Type Assertions

1.3.0 · active · verified Sun Apr 19

ts-expect provides a set of lightweight utilities designed for compile-time TypeScript type assertions. Its primary function, `expectType`, takes a value and a generic type, leveraging the TypeScript compiler to ensure the value is assignable to the generic type without performing any runtime checks. The current stable version is v1.3.0, with releases typically adding new utility functions or refining existing type definitions. Key differentiators include its minimalistic approach, relying solely on TypeScript's type system for validation, making it an excellent tool for testing type definitions within a project's codebase. It avoids the overhead of more complex type-checking frameworks like `dtslint` by focusing on direct, in-code type assertions, making it ideal for maintaining type correctness during refactoring or when developing complex generics.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates basic compile-time type assertions with `expectType`, strict type comparisons using `TypeEqual`, and ensuring exhaustive handling of union types with `expectNever`, all without runtime execution.

import { expectType, TypeEqual, expectNever } from "ts-expect";

// --- Basic expectType assertions ---
// These checks are performed at compile-time by TypeScript.
expectType<string>("hello world");
expectType<number>(42);

// The following line would cause a compile-time error:
// expectType<boolean>("true"); // Type 'string' is not assignable to type 'boolean'.

// --- Using TypeEqual for stricter type comparisons ---
// TypeEqual is a utility type to ensure two types are exactly the same.
interface User {
  id: string;
  name: string;
}

type AdminUser = { id: string; name: string; roles: string[] };

// Expects that User and AdminUser are NOT equal, so asserting 'false' should pass.
expectType<TypeEqual<User, AdminUser>>(false);

// The following would cause a compile-time error if types were not equal:
// expectType<TypeEqual<User, { id: string; name: string }>>(false); // Type 'false' is not assignable to type 'true'.

// --- Exhaustive checks with expectNever ---
// expectNever is useful for ensuring all cases in a discriminated union or switch statement are handled.
type TrafficLight = "red" | "yellow" | "blue"; // Typo: 'blue' should likely be 'green'

function getAction(light: TrafficLight): string {
  switch (light) {
    case "red":
      return "Stop";
    case "yellow":
      return "Prepare to stop";
    // If 'green' was intended and 'blue' added, this 'default' will catch unhandled types.
    default:
      // This line will trigger a TypeScript error if 'light' is not assignable to 'never'.
      // It helps catch unhandled cases in unions at compile time.
      return expectNever(light); // Expects 'light' to be 'never' here.
  }
}

getAction("red");
getAction("yellow");
// The 'blue' case will cause a compile-time error due to expectNever if it's not handled.
// This demonstrates a powerful pattern for ensuring type safety in complex logic.

view raw JSON →