fix(structures): widen via String() in narrowing test to satisfy lint #231

Merged
julien merged 1 commits from fix/structure-kind-spec-lint into main 2026-05-26 13:36:43 +02:00
Owner

Summary

One-line lint fix in apps/portal-bff/src/structures/structure-kind.spec.ts — the narrowing test failed CI lint with @typescript-eslint/no-inferrable-types on const candidate: string = 'medico_social'.

The naive fix (drop the annotation) would make the test vacuous: TypeScript would infer the literal type 'medico_social', which is already a StructureKind subtype, so the runtime guard isStructureKind would have nothing to prove. Fix instead: widen via String('medico_social') — the inferred return type is string, the narrowing check stays meaningful, the linter is happy.

What lands

File Change
apps/portal-bff/src/structures/structure-kind.spec.ts const candidate: string = 'medico_social'const candidate = String('medico_social'). 3-line comment explains why String() rather than dropping the annotation.

Test plan

  • pnpm exec nx lint portal-bff0 errors, 13 warnings (warnings all pre-existing in unrelated files).
  • pnpm exec prettier --check clean.
  • CIpnpm ci:check passes on this PR.
  • Review focus — the comment block explaining the round-trip rationale (otherwise the String('literal') pattern reads like over-engineering).

Notes for the reviewer

  • Pre-existing warnings are NOT addressed here. The 13 remaining lint warnings (non-null assertions in principal-extractor.spec.ts, unused underscored params in rate-limit.middleware.ts, one stale eslint-disable in downstream-token-cache.service.spec.ts) are outside the scope of this PR — none of them block CI today, and folding them in would muddle the diff. Worth a separate chore(bff): sweep lint warnings PR if/when those become noisy.
  • Why String() over an as string cast? Both would work, but String() is a real runtime operation (returns a fresh string) — as string is type-system-only. The runtime call has a tiny side-effect (and the inferred return type really IS string, not the literal), so the narrowing test stays semantically real.
  • No new error class. The lint rule @typescript-eslint/no-inferrable-types is set to error severity in the workspace config; my narrowing test was just the first case to trip it.
## Summary One-line lint fix in [apps/portal-bff/src/structures/structure-kind.spec.ts](apps/portal-bff/src/structures/structure-kind.spec.ts) — the narrowing test failed CI lint with `@typescript-eslint/no-inferrable-types` on `const candidate: string = 'medico_social'`. The naive fix (drop the annotation) would make the test vacuous: TypeScript would infer the literal type `'medico_social'`, which is already a `StructureKind` subtype, so the runtime guard `isStructureKind` would have nothing to prove. Fix instead: widen via `String('medico_social')` — the inferred return type is `string`, the narrowing check stays meaningful, the linter is happy. ## What lands | File | Change | | --- | --- | | `apps/portal-bff/src/structures/structure-kind.spec.ts` | `const candidate: string = 'medico_social'` → `const candidate = String('medico_social')`. 3-line comment explains why `String()` rather than dropping the annotation. | ## Test plan - [x] `pnpm exec nx lint portal-bff` — `0 errors, 13 warnings` (warnings all pre-existing in unrelated files). - [x] `pnpm exec prettier --check` clean. - [ ] **CI** — `pnpm ci:check` passes on this PR. - [ ] **Review focus** — the comment block explaining the round-trip rationale (otherwise the `String('literal')` pattern reads like over-engineering). ## Notes for the reviewer - **Pre-existing warnings are NOT addressed here.** The 13 remaining lint warnings (non-null assertions in `principal-extractor.spec.ts`, unused underscored params in `rate-limit.middleware.ts`, one stale eslint-disable in `downstream-token-cache.service.spec.ts`) are outside the scope of this PR — none of them block CI today, and folding them in would muddle the diff. Worth a separate `chore(bff): sweep lint warnings` PR if/when those become noisy. - **Why `String()` over an `as string` cast?** Both would work, but `String()` is a real runtime operation (returns a fresh `string`) — `as string` is type-system-only. The runtime call has a tiny side-effect (and the inferred return type really IS `string`, not the literal), so the narrowing test stays semantically real. - **No new error class.** The lint rule `@typescript-eslint/no-inferrable-types` is set to `error` severity in the workspace config; my narrowing test was just the first case to trip it.
julien added 1 commit 2026-05-26 13:36:01 +02:00
fix(structures): widen via String() in narrowing test to satisfy lint
CI / commits (pull_request) Successful in 2m44s
CI / scan (pull_request) Successful in 2m53s
CI / a11y (pull_request) Successful in 3m42s
CI / perf (pull_request) Successful in 8m39s
CI / check (pull_request) Failing after 12m35s
377a484afc
The narrowing test for `isStructureKind` had `const candidate: string =
'medico_social'`, which ESLint's `@typescript-eslint/no-inferrable-types`
correctly flags as trivially-inferred.

The naive fix - dropping the annotation - would let TypeScript infer
the literal type `'medico_social'`, which is already a StructureKind
subtype. The narrowing check would then be vacuous (TypeScript already
knows the value is a kind, the runtime guard has nothing to prove).

Fix: round-trip through `String()` to widen the literal to `string`.
TypeScript infers `string` for `String(...)` return; no annotation
needed; the narrowing test stays meaningful.

CI lint target on portal-bff now passes 0 errors. The 13 remaining
warnings (non-null assertions in principal-extractor.spec, unused
underscored params in rate-limit.middleware, etc.) are pre-existing
and not in scope for this fix.
julien merged commit cba36394c9 into main 2026-05-26 13:36:43 +02:00
julien deleted branch fix/structure-kind-spec-lint 2026-05-26 13:36:45 +02:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: julien/apf_portal#231