Skip to content

Optional chaining on indexed reads is load-bearing at runtime and invisible to the compiler #47

Description

@bmethod

Source: found while checking a review claim on #42, 2026-09-10. The claim was that a property access failed the strict type check. It does not, and establishing why exposed something worth more.

tsconfig.json sets strict: true but not noUncheckedIndexedAccess. So items[selected] has type SettingItem, not SettingItem | undefined — even where the author annotated the binding as possibly undefined, because a const initialised with a narrower value is narrowed to the initializer's type for every later read. The annotation is documentation; the compiler reads the initializer.

Proved with a deliberate probe rather than assumed: assigning that binding to a number reports Type 'SettingItem' is not assignable to type 'number', naming the narrowed type.

The consequence is that every ?. on an indexed read in src/ui/settings-screen.tsx is load-bearing at runtime and invisible to the compiler. One of them was missing and nothing reported it; the index can be -1 since a recent fix made a no-match query select no row, so the access would have thrown rather than refused. It was found by a reviewer reading the file, not by any check.

Nothing reports the next one that goes missing.

Done when

  • noUncheckedIndexedAccess is on, or an equivalent check reports an unguarded indexed read.
  • The fallout is fixed rather than suppressed — the flag will surface every indexed read in the tree, and each is either genuinely guarded or a latent throw.

Context

  • Location: tsconfig.json, and whatever the flag surfaces. src/ui/settings-screen.tsx is where it was found and is unlikely to be the only place.
  • This is repository-wide and deliberately not done inside a feature branch.
  • Related: The test suite prints render warnings and fails on none of them #37 and kendex#2518 — checks that report success while not checking.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions