Files
atomic-design-poc/docs/backlog/WP-06-typed-async.md
Edwin van den Houdt f769242f76 docs: replace SHOWCASE-ROADMAP.md with docs/backlog/ (17 WPs)
Turns the prior roadmap sketch into ordered, gated work packages (enforcement
gates, FP/DDD consistency, CIBG fidelity, Storybook curriculum, a11y) from the
2026-07-02 showcase-hardening audit.
2026-07-02 17:07:59 +02:00

2.3 KiB
Raw Blame History

WP-06 — Generic async template contexts: kill $any() (18×)

Status: todo Phase: 1 — FP/DDD core

Why

18 $any() casts in templates defeat strict template checking. Root cause for ~9 of them: AsyncLoadedDirective types its template context as { $implicit: unknown } (src/app/shared/ui/async/async.component.ts), so every <ng-template appAsyncLoaded let-p> consumer must cast. The rest are template union-narrowing workarounds.

Read first

  • src/app/shared/ui/async/async.component.ts (component + directives)
  • Consumers with $any: src/app/registratie/ui/dashboard.page.ts, registration-detail.page.ts, registration-summary/registration-summary.component.ts (×5, union peeking), registratie-wizard.component.ts (×4, step data), src/app/showcase/ui/concepts.page.ts (×2)

Decisions (pre-made, don't relitigate)

  • Fix the root cause with generics + static ngTemplateContextGuard, not per-consumer casts.
  • Fallback (only if Angular's inference fights the RemoteData<E,T> | Resource<T> union input): split into two typed inputs (data / resource) — record the swap here.

Files

  • src/app/shared/ui/async/async.component.tsAsyncComponent<T>; AsyncLoadedDirective<T> with static ngTemplateContextGuard<T>(dir, ctx): ctx is { $implicit: T } (same for the failure directive's error type if applicable)
  • Every $any() call site (grep -rn '\$any(' src/app)

Steps

  1. Make the async component/directives generic; keep the public API otherwise identical.
  2. Remove the now-unneeded $any()s in async consumers.
  3. Remaining union narrowing: replace with @switch on the status tag (registration-summary) or small typed computed() getters (wizard step data, showcase fake resource).
  4. npm run build (strict templates) is the real check here.

Acceptance criteria

  • grep -rn '\$any(' src/app → zero hits.
  • No as casts added to compensate in component classes (typed getters are fine).
  • Build green with strict template checking.

Verification

GREEN + npm run test-storybook:ci. Smoke: dashboard + registration detail render.

Out of scope

Brief page's <app-async> adoption (WP-07 — it depends on this WP's typing).

Risks

Angular generic-component inference edge cases — the documented fallback keeps the WP bounded.