🐛 Narrow union-valued and optional discriminants
The tagged-union matcher selected handler parameters with
`Extract<T, Record<K, V>>`, which only keeps a member whose
discriminant is a singleton literal. A property that is itself a
union (`{ color: "red" | "green" | "blue" }`) or optional
(`{ type?: "x" }`) matched no member, so every handler received
`never`, and the fallback saw the whole shape instead of the
unhandled tags.
Replace the selector with `Narrowed`, which distributes over `T`,
drops a member whose `K` cannot take the tag, and narrows `K`. The
`T[K] extends V` fast path keeps an exact member (a discriminated
union's declared interface) untouched. The fallback reuses
`Narrowed` over `Exclude<Tags, HandledTags>`, so a union-valued
property narrows to the unhandled tags rather than the whole shape.
Matching a defined tag on an optional property makes the key
required (`{ type: "x" }`); the `undefined` tag yields
`{ type?: never }` under `exactOptionalPropertyTypes` (absence) or
`{ type?: undefined }` when the property admits an explicit
`undefined`.
This commit is contained in:
1 parent
e7b5c0284d
commit
55bf6c24a7
5 files changed
+357
-25
No files matched your search
+2
-2
@@ -17,10 +17,10 @@ v1.0:
|
||||
☐ Achieve 100% branch coverage on `src/index.ts`
|
||||
|
||||
Matcher:
|
||||
☐ when using a union type as a property, the current behavior of tagged union matcher is
|
||||
✔ when using a union type as a property, the current behavior of tagged union matcher is @done
|
||||
to pass never to handler parameters
|
||||
→ new matcher function needed or can be fixed in tagged union matcher
|
||||
☐ optional discriminant (`{ type?: "x" }`) is the same hole: the boolean/nullish change now admits the `undefined` tag, so the factory accepts the key, but `Extract<T, Record<K, V>>` still passes `never` to both the `x` and `undefined` handlers
|
||||
✔ optional discriminant (`{ type?: "x" }`) is the same hole: the boolean/nullish change now admits the `undefined` tag, so the factory accepts the key, but `Extract<T, Record<K, V>>` still passes `never` to both the `x` and `undefined` handlers @done
|
||||
|
||||
Documentation:
|
||||
☐ Bring README.md back to its previous form — synopsis and examples restored, in the correct place
|
||||
|
||||
Reference in new issue
Block a user