🐛 Reject mixed literal and broad universes

`UnsupportedReason` tested `IsLiteral<PatternKey<T>> extends false`.
`IsLiteral` is `boolean` for a union that mixes a literal with a broad
type (`"a" | \`x-${number}\``), so `boolean extends false` is false and
the mix was accepted. Test `extends true` instead, which rejects it.

Found while adding property-union broad-universe coverage; the gate is
shared with the primitive-union matcher.
This commit is contained in:
tmu committed 2026-09-23 16:32:09 +00:00
1 parent 55bf6c24a7
commit 1bdf7f0315
4 files changed
+13 -5

No files matched your search

+5 -5
View File
@@ -62,11 +62,11 @@ export type Collisions<T> = Extract<T, Stringified<T>>;
// universe is a finite union of literals with no value/stringification
// collision: only then can `PatternKey` be inverted unambiguously.
export type UnsupportedReason<T extends Matchable> =
IsLiteral<PatternKey<T>> extends false
? "broad types like string, number and template literals are not supported"
: [Collisions<T>] extends [never]
? never
: `a value and its stringification collide. Value is "${Collisions<T> & string}"`;
IsLiteral<PatternKey<T>> extends true
? [Collisions<T>] extends [never]
? never
: `a value and its stringification collide. Value is "${Collisions<T> & string}"`
: "broad types like string, number and template literals are not supported";
// The diagnostic for an unsupported universe. Extends `HandlerMap` so the
// implementation's `handlers: HandlerMap` stays assignable when the gate is
+2
View File
@@ -528,6 +528,8 @@ test("getPrimitiveUnionMatcher: a broad universe is rejected", () => {
getPrimitiveUnionMatcher<number>()({ 1: () => 1 });
// @ts-expect-error a template literal is open
getPrimitiveUnionMatcher<`a${string}`>()({ a: () => 1 });
// @ts-expect-error a literal mixed with a template literal is open
getPrimitiveUnionMatcher<"a" | `x-${number}`>()({ a: () => 1 });
// @ts-expect-error `string | boolean` is open because of `string`
getPrimitiveUnionMatcher<string | boolean>()({ true: () => 1 });
// @ts-expect-error the widening factory rejects broad universes too