The exact-equality `toEqualTypeOf` assertions already reject `any`, so the `.not.toBeAny()` guards were redundant. Refresh the fixture header and development/ci.md to match.
90 lines
2.9 KiB
TypeScript
90 lines
2.9 KiB
TypeScript
// 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 rejects `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<ResultCode>()({
|
|
ok: (s) => {
|
|
expectTypeOf(s).toEqualTypeOf<"ok">();
|
|
return "OK";
|
|
},
|
|
created: (s) => {
|
|
expectTypeOf(s).toEqualTypeOf<"created">();
|
|
return "CREATED";
|
|
},
|
|
});
|
|
|
|
expectTypeOf(toStatus).toEqualTypeOf<(shape: ResultCode) => string>();
|
|
|
|
// The widening twin keeps each handler's own return type in the union.
|
|
const toStatusW = getPrimitiveUnionMatcherW<ResultCode>()(
|
|
{
|
|
ok: (s) => {
|
|
expectTypeOf(s).toEqualTypeOf<"ok">();
|
|
return "OK" as const;
|
|
},
|
|
},
|
|
(rest) => {
|
|
expectTypeOf(rest).toEqualTypeOf<"created">();
|
|
return "CREATED" as const;
|
|
},
|
|
);
|
|
|
|
expectTypeOf(toStatusW).toEqualTypeOf<
|
|
(shape: ResultCode) => "OK" | "CREATED"
|
|
>();
|
|
|
|
type Contact =
|
|
| { kind: "email"; address: string }
|
|
| { kind: "phone"; number: string };
|
|
|
|
const format = getTaggedUnionMatcher<Contact>()("kind")({
|
|
email: (e) => {
|
|
expectTypeOf(e).toEqualTypeOf<{ kind: "email"; address: string }>();
|
|
return e.address;
|
|
},
|
|
phone: (p) => {
|
|
expectTypeOf(p).toEqualTypeOf<{ kind: "phone"; number: string }>();
|
|
return p.number;
|
|
},
|
|
});
|
|
|
|
expectTypeOf(format).toEqualTypeOf<(shape: Contact) => string>();
|
|
|
|
const formatW = getTaggedUnionMatcherW<Contact>()("kind")(
|
|
{
|
|
email: (e) => {
|
|
expectTypeOf(e).toEqualTypeOf<{ kind: "email"; address: string }>();
|
|
return e.address;
|
|
},
|
|
},
|
|
(rest) => {
|
|
expectTypeOf(rest).toEqualTypeOf<{ kind: "phone"; number: string }>();
|
|
return rest.number;
|
|
},
|
|
);
|
|
|
|
expectTypeOf(formatW).toEqualTypeOf<(shape: Contact) => string>();
|
|
|
|
export { format, formatW, toStatus, toStatusW };
|