// Consumer smoke test for the minimum supported TypeScript (see README // § Requirements). It imports the package by name, so it resolves through the // `exports` map to the emitted `dist/*.d.ts` — including the relative `.ts` // specifiers they keep — rather than to the source. Run by `npm run test:compat` // and the CI `compat` job only; never by `check` / `verify`. // // Why the `expectTypeOf` assertions: a compile that merely succeeds is a weak // oracle. An `any`-typed declaration would compile, but `expect-type`'s exact // equality and `.not.toBeAny()` reject `any`, so the assertions prove the // emitted types are real. Every handler *parameter* is asserted too, not just // the matcher: the handler's member type comes from the `Member` inversion in // the declarations, and a wrong or `any` parameter would otherwise slip // through, since the matcher's own `(shape: T) => R` type is built from `T` and // the handler returns. See development/ci.md § TypeScript compatibility. import { expectTypeOf } from "expect-type"; import { getPrimitiveUnionMatcher, getPrimitiveUnionMatcherW, getTaggedUnionMatcher, getTaggedUnionMatcherW, } from "tiny-pattern-ts"; type ResultCode = "ok" | "created"; const toStatus = getPrimitiveUnionMatcher()({ ok: (s) => { expectTypeOf(s).not.toBeAny(); expectTypeOf(s).toEqualTypeOf<"ok">(); return "OK"; }, created: (s) => { expectTypeOf(s).not.toBeAny(); expectTypeOf(s).toEqualTypeOf<"created">(); return "CREATED"; }, }); expectTypeOf(toStatus).not.toBeAny(); expectTypeOf(toStatus).toEqualTypeOf<(shape: ResultCode) => string>(); // The widening twin keeps each handler's own return type in the union. const toStatusW = getPrimitiveUnionMatcherW()( { ok: (s) => { expectTypeOf(s).not.toBeAny(); expectTypeOf(s).toEqualTypeOf<"ok">(); return "OK" as const; }, }, (rest) => { expectTypeOf(rest).not.toBeAny(); expectTypeOf(rest).toEqualTypeOf<"created">(); return "CREATED" as const; }, ); expectTypeOf(toStatusW).not.toBeAny(); expectTypeOf(toStatusW).toEqualTypeOf< (shape: ResultCode) => "OK" | "CREATED" >(); type Contact = | { kind: "email"; address: string } | { kind: "phone"; number: string }; const format = getTaggedUnionMatcher()("kind")({ email: (e) => { expectTypeOf(e).not.toBeAny(); expectTypeOf(e).toEqualTypeOf<{ kind: "email"; address: string }>(); return e.address; }, phone: (p) => { expectTypeOf(p).not.toBeAny(); expectTypeOf(p).toEqualTypeOf<{ kind: "phone"; number: string }>(); return p.number; }, }); expectTypeOf(format).not.toBeAny(); expectTypeOf(format).toEqualTypeOf<(shape: Contact) => string>(); const formatW = getTaggedUnionMatcherW()("kind")( { email: (e) => { expectTypeOf(e).not.toBeAny(); expectTypeOf(e).toEqualTypeOf<{ kind: "email"; address: string }>(); return e.address; }, }, (rest) => { expectTypeOf(rest).not.toBeAny(); expectTypeOf(rest).toEqualTypeOf<{ kind: "phone"; number: string }>(); return rest.number; }, ); expectTypeOf(formatW).not.toBeAny(); expectTypeOf(formatW).toEqualTypeOf<(shape: Contact) => string>(); export { format, formatW, toStatus, toStatusW };