Skip to content

Compile under strict consumer tsconfigs (noUncheckedIndexedAccess, declaration, ES2022 lib) - #215

Merged
deebov merged 1 commit into
mainfrom
fix/strict-tsconfig
Sep 27, 2026
Merged

deebov merged 1 commit into
mainfrom
fix/strict-tsconfig

Conversation

@deebov

@deebov deebov commented Sep 27, 2026

Copy link
Copy Markdown
Contributor

Our source failed to type-check in shadcn/ui projects with stricter tsconfigs (found by the shadcn installation test: empty-state.tsx, input-payment.tsx, input-tags.tsx, shared-assets/illustrations/index.tsx). This fixes every error the free components produce under the strictest realistic consumer settings, without changing rendered output.

Harness

A throwaway project type-checks both repos together (@/components/* → react-pro then react, as in the website's tsconfig; TypeScript 6.0.3), combining the shadcn next-monorepo packages/typescript-config/base.json + react-library.json with create-vite's react-ts tsconfig.app.json:

strict, noUncheckedIndexedAccess, declaration + declarationMap (emitDeclarationOnly to a scratch dir), isolatedModules, verbatimModuleSyntax, erasableSyntaxOnly, noUnusedLocals, noUnusedParameters, noFallthroughCasesInSwitch, moduleDetection: force, esModuleInterop, resolveJsonModule, skipLibCheck, target: ES2022, lib: [ES2022, DOM, DOM.Iterable] (monorepo base; also re-run with the Vite template's ES2023), jsx: react-jsx, module: esnext + moduleResolution: bundler.

Not used: the monorepo base's module/moduleResolution: NodeNext (its extension rules are about the consumer's package layout, not our source), and exactOptionalPropertyTypes (in neither template; 797 errors across both repos, not addressed here).

Served files = components/**, hooks/**, utils/**, examples/** minus *.story.tsx, *.demo.tsx, emails/**; stories/demos are counted separately.

Errors in this repo (before → after)

Flag Served files Stories/demos
noUncheckedIndexedAccess 11 → 0 4 → 0
declaration (TS4023) 4 → 0 –
lib: ES2022 (toReversed, Iterator.prototype.toArray) 2 → 0 –
everything else listed above 0 0

(toArray is ES2025, so it also failed under the Vite template's ES2023 lib.)

What changed

  • Narrowed possibly-undefined array reads: empty-state (slot guard, optional size class), input-tags (last-tag guards), input-payment (named unknownCardType fallback instead of cardTypes[length - 1]), avatar/utils (getInitials default), dropdown-button-link (initial state literal), table.demo.
  • Exported the per-file IllustrationProps in box/cloud/credit-card/documents so the Illustration map can be named in emitted .d.ts files.
  • payload?.toReversed() → [...payload].reverse(); keys.keys().toArray() → Array.from(keys).
  • tsconfig.json: added noUncheckedIndexedAccess, verbatimModuleSyntax, erasableSyntaxOnly, declaration (reports TS4023 even with noEmit, checked by reverting one export), and lib esnext → es2022, so these can't regress.

No !, any or @ts-ignore. The only runtime differences are in inputs that used to throw (e.g. getInitials("Olivia") returned "O" + crash; now "O").

Verification

  • Harness: 0 errors for served files, stories/demos, under both ES2022 and ES2023 libs (together with the react-pro PR).
  • bun run test (tsc with the new flags, ESLint, Prettier): passes.

Companion PR: untitleduico/react-pro (same branch name). Once both land, the website's generated registry manifests need a refresh.

🤖 Generated with Claude Code

Fixes the errors our source produces in shadcn/ui projects that compile with
noUncheckedIndexedAccess, declaration emit and an ES2022 lib (the shadcn
monorepo template), without changing rendered output:

- narrow possibly-undefined array reads (empty-state, input-tags, input-payment,
  avatar utils, dropdown-button-link, table demo)
- export the per-file IllustrationProps so the Illustration map can be named
  in emitted declarations (TS4023)
- replace ES2023+/ES2025 APIs with equivalents available in ES2022
  (toReversed in charts-base, Iterator.prototype.toArray in dropdown-button-link)

tsconfig now enables noUncheckedIndexedAccess, verbatimModuleSyntax,
erasableSyntaxOnly and declaration, and uses the es2022 lib, so these can't
regress.
@deebov
deebov merged commit 4702dc0 into main Sep 27, 2026
1 check passed
@deebov
deebov deleted the fix/strict-tsconfig branch September 27, 2026 01:33
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