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`.
47 lines
2.7 KiB
Plaintext
47 lines
2.7 KiB
Plaintext
Tasks
|
|
|
|
Backlog and tracking for tiny-pattern-ts. Managed in vscode-todotasks format.
|
|
|
|
---
|
|
|
|
Setup:
|
|
☐ Split off template into separate package => pi --session 01a07dde-7050-7054-bb36-1606d7eb2bc3 @low
|
|
|
|
v1.0:
|
|
☐ API surface is stable and fully typed
|
|
☐ Finalize public exports in `src/index.ts`
|
|
☐ Document all exported types and functions
|
|
☐ Add JSDoc for public APIs
|
|
☐ Test coverage meets threshold
|
|
☐ Achieve 100% branch coverage on `src/primitive-union.ts`
|
|
☐ 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 @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 @done
|
|
|
|
Documentation:
|
|
☐ Bring README.md back to its previous form — synopsis and examples restored, in the correct place
|
|
→ previous section order: title, tagline, Synopsis, Description, Requirements, Examples, API, License, Contributing
|
|
→ previous Examples order: literal/exhaustive, typeof, structural/discriminated unions, when, any
|
|
☐ Create `examples/` directory with runnable snippets
|
|
☐ Add comparison section vs. other TS pattern-matching libs in Readme.md
|
|
☐ Write migration guide for users coming from discriminated unions
|
|
☐ Create backlog tasks for implementation
|
|
☐ Validate code fences in Markdown (start with README.md) — compile the TypeScript examples against `src/` so the docs cannot drift from the API
|
|
|
|
Maintenance:
|
|
☐ Serve CI coverage over a tiny self-hosted webserver (replace the zip artifact) @low
|
|
☐ Explore serving coverage for non-tag pushes (e.g. `main/coverage`, PR previews) @low
|
|
→ design: no deploy step in CI; the webserver just exposes the shared directory (decided over Gitea Pages / Codecov — neither confirmed available/ wanted)
|
|
☐ serve docs over self hosted server @low
|
|
☐ Add a minimal dir-listing webserver to the gitea docker setup for serving docs (reuse existing reverse proxy)
|
|
☐ CI writes docs to a shared volume keyed by project + tag (e.g. `/docs/tiny-pattern-ts/<tag>/`)
|
|
☐ Browse to `…/docs/<repo>/<tag>/index.html` in the browser
|
|
☐ serve landing page over self hosted server @low
|
|
☐ Add a minimal dir-listing webserver to the gitea docker setup for serving landing page (reuse existing reverse proxy)
|
|
☐ CI writes landing page to a shared volume keyed by project + tag (e.g. `/landing/tiny-pattern-ts/<tag>/`)
|
|
☐ Browse to `…/tiny-pattern-ts/index.html` in the browser
|