Skip to content

fix: restore strict tsconfig flags and fix all violations#12

Merged
dogmar merged 12 commits into
mainfrom
fix/typecheck-gate
Jun 13, 2026
Merged

fix: restore strict tsconfig flags and fix all violations#12
dogmar merged 12 commits into
mainfrom
fix/typecheck-gate

Conversation

@dogmar

@dogmar dogmar commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

Audit fix A (1 of 5). PR #9 wired type-aware linting into the gate (vp lint now runs the TypeScript checker) but made the pre-existing errors disappear by deleting noUncheckedIndexedAccess, exactOptionalPropertyTypes, and noPropertyAccessFromIndexSignature from the root tsconfig. This PR restores all three flags and fixes the ~190 violations they surface, so the gate now enforces the strictness the codebase was written against.

Real bug fixed

resolveFocusTarget (package/src/utils.ts) returned undefined — despite promising Temporal.PlainDate — when the weeks grid was empty. It now falls back to focusedDate (its own non-optional parameter), with a regression test covering both polyfill variants. TDD: test written first, watched fail, then fixed.

Fix patterns (behavior-preserving)

  • noUncheckedIndexedAccess: real narrowing where practical; non-null assertions only where the bounds invariant is locally obvious (loop-bounded parallel arrays, literal two-element tuples). Freely used in test files.
  • exactOptionalPropertyTypes: conditional spreads (...(x !== undefined && { x })) at call sites; no shared/public type was widened except DayCellInstanceProps.columnIndex (declared and consumed in day-cell.tsx).
  • computeSelectionUpdate's committedDates param is now readonly (it never mutates), and computePreviewRange models "no committed range" as undefined instead of casts.
  • No as any, no @ts-expect-error, no semantic fallback values inserted.

Verification

  • vp run ready exits 0: format clean, lint (with type checking) 0 warnings / 0 errors, package 666/666 tests, website 54/54.
  • Reviewed by a pre-commit review pass, which caught 2 missed violations in root-selection.ts (both fixed) and confirmed the temporal-polyfill date-math changes are equivalence-preserving.

🤖 Generated with Claude Code

dogmar and others added 3 commits June 12, 2026 16:06
PR #9 enabled type-aware linting in the gate but removed
noUncheckedIndexedAccess, exactOptionalPropertyTypes, and
noPropertyAccessFromIndexSignature instead of fixing the ~190
violations they flagged. This restores all three flags and fixes
every violation, behavior-preserving except one real bug:

resolveFocusTarget returned undefined (despite promising PlainDate)
when the weeks grid was empty; it now falls back to focusedDate,
with a regression test.

Fix patterns: real narrowing or locally-obvious non-null assertions
for indexed access; conditional spreads for optional props under
exactOptionalPropertyTypes; readonly param for computeSelectionUpdate.
No as-any, no ts-expect-error, no semantic fallbacks.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Review feedback on the strict-flags fix: the indexed-access assertions
were unwarranted. All ~97 added assertions are now real checks:

- weeks-grid: iterate .entries() carrying the element; guards on the
  parallel-array reads
- temporal-polyfill: malformed ISO strings now throw RangeError
  (matching real Temporal) instead of NaN-propagating; formatToParts
  reads collapse into named locals with one completeness check
- grid-header: index prop is validated (genuinely reachable for a
  public prop) instead of asserted
- tests: vitest/chai assert() narrowing on mock calls and grid lookups;
  median/p95 helpers take a length guard instead of per-index asserts

No new assertions, no as-any, no expectation changes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@dogmar

dogmar commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator Author

Replaced all ~97 non-null assertions from the original push with real narrowing checks (loop restructures via .entries(), named-local guards, vitest assert() in tests). One deliberate behavior change worth noting: the mini temporal-polyfill now throws RangeError on malformed ISO strings — matching real Temporal — where it previously NaN-propagated silently. Gate green: lint 0/0, 666+54 tests passing.

dogmar and others added 6 commits June 12, 2026 16:31
Real narrowing checks stay in source files only; the assert()
conversions in tests added noise without value.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@dogmar dogmar force-pushed the fix/typecheck-gate branch from 7f4f641 to 6c755e1 Compare June 13, 2026 00:06
dogmar and others added 2 commits June 12, 2026 17:22
The destructure `const [weekStart, weekEnd] = weekDays` took the week's
second day as its end, flipping the inactive early-exit and extendsAfter
for any week longer than two days. Restore the last-element read while
keeping the INACTIVE_RANGE_INFO refactor.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@dogmar dogmar force-pushed the fix/typecheck-gate branch from 306d426 to 73eb765 Compare June 13, 2026 00:29
@dogmar dogmar merged commit c707166 into main Jun 13, 2026
6 checks passed
@dogmar dogmar deleted the fix/typecheck-gate branch June 13, 2026 01:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant