Skip to main content

How duck-ttest compares

Honest tradeoffs versus tsd, expect-type, and type-fest.

The TypeScript ecosystem already has three well-known options that overlap with duck-ttest. Pick the right tool for your situation.

The space

duck-ttesttsdexpect-typetype-fest
What it isAssertion API + utility libraryAssertion API, CLI runnerAssertion API, fluentUtility library
RunnerYour tsc --noEmitBundled CLI on top of tscYour tsc --noEmitn/a types only
Assertion styleAssertTrue<Equal<X, Y>, Msg>expectType<X>(value)expectTypeOf(value).toEqualTypeOf<X>()n/a
Strict equalityEqual<X, Y> (variance-preserving)expectType is structural.toEqualTypeOf is variance-preservingn/a
Utility breadth35 modules guards, brands, SQL, router, fp, geometry, ...NoneNoneBroad object/string/number utilities
Runtime costZero (type-only)ZeroZero (compile time) small runtime function for fluent APIZero
Custom error messagesMsg generic on every assertionTS diagnosticTS diagnosticn/a
Sub-path importsPer-moduleSingle importSingle importPer-utility
Best forSchema generators, ORMs, type-heavy SDKsPublic APIs that ship type testsDrop-in expect-style ergonomicsStocking your own type lib

When to pick duck-ttest

  • You want assertions and a utility library in one package.
  • You already structure your tests around tsc --noEmit.
  • You care about distinguishing any from unknown (use Equal, not extends-extends).
  • You ship a framework where the type system itself is the contract (schema builders, ORMs, routers).

When to pick tsd instead

  • Your library publishes a .d.ts and you want a CLI that runs over a test-d/ folder as part of npm test.
  • You don't care about a custom utility library — only assertion ergonomics.

When to pick expect-type instead

  • You want a .toEqualTypeOf<T>() fluent style for readability.
  • You don't need a utility library next door.

When to pick type-fest instead

  • You only need utility types (Simplify, RequireAtLeastOne, Get, ...).
  • You don't write assertions.

duck-ttest can be used alongside any of the above. They aren't mutually exclusive — type-fest's utilities will type-check just fine in a duck-ttest assertion.

What duck-ttest is not

  • Not a runtime test runner. Use vitest / jest / bun-test for runtime behavior; pair them with duck-ttest for the type side.
  • Not a CLI. There is no ttest binary. tsc --noEmit is the runner.
  • Not a Zod / Valibot alternative. Those validate values at runtime. duck-ttest only checks types at compile time.

See also