Skip to content

fix(types): import React in files whose emitted declarations use React.* - #128

Open
david-roper wants to merge 2 commits into
DouglasNeuroInformatics:mainfrom
david-roper:package-react-fix
Open

david-roper wants to merge 2 commits into
DouglasNeuroInformatics:mainfrom
david-roper:package-react-fix

Conversation

@david-roper

Copy link
Copy Markdown
Contributor

fix(types): import React in files whose emitted declarations use React.*

following steps provided in #126

Problem

Since 6.18.0, some published .d.ts files reference React.* without importing it. For example, dist/components/Checkbox/Checkbox.d.ts:

export declare const Checkbox: ({ className, ref, ...props }: React.ComponentProps<typeof CheckboxPrimitive.Root>) => React.JSX.Element;

This only resolves if the consumer's program has a global React namespace, which @types/react provides via export as namespace React. Consumers without that global get TS2503: Cannot find namespace 'React'. With skipLibCheck: true that error is hidden, and the props silently become any.

Open Data Capture is one such consumer: it overrides @types/react with a vendored react package whose types have no export as namespace React. With 6.18.0, apps/web gets 17 × TS7006 (43 × TS2503 with skipLibCheck: false).

Cause: #124 (replace forwardRef with ref as a prop) moved bare React.* types from forwardRef generic arguments, which were only used for inference, into parameter annotations. Declaration emit copies parameter annotations as written. Compound components built with Object.assign (Table, Tabs, Select, DropdownMenu, Sheet, HoverCard) inherit the bare references from their subcomponents. In total, 48 of 204 emitted .d.ts files were affected.

Newly affected in 6.18.0:

  • Checkbox, DropdownButton, Label, Separator, Slider
  • DropdownMenu.* items, HoverCard.Content, Select.*, Sheet.{Title,Description}
  • Table, Table.*, Tabs, Tabs.*
  • the ref of Tooltip.Trigger

Form / FormProps (5 errors) was already affected in 6.17.0.

Changes

1. Type-only React imports

  • Adds import type * as React from 'react'; to the 49 files that use React.* without importing it: 45 published files plus 4 story/spec files.
  • This matches the namespace style already used in the codebase. Rewriting to named imports would touch ~94 files with no added safety.
  • Emitted .js and .css are byte-identical to before. Only .d.ts files (and .js.map line offsets) change.
  • Compound declarations such as Table.d.ts now emit import("react").ComponentProps<…>.

2. Guard against regressions: pnpm lint:dist

libui's own tsc can't catch this, because @types/react provides the global. So this PR adds scripts/check-dist-types.js, which:

  • type-checks every dist/**/*.d.ts with skipLibCheck: false
  • removes export as namespace React; from @types/react in memory first, to reproduce a consumer without the global
  • fails if dist is empty, if no @types/react file was read, or if the global wasn't found, so a future change to @types/react can't make it pass silently

It's wired into:

  • package.json: "lint:dist": "node scripts/check-dist-types.js" (run after pnpm build)
  • test.yaml: Build and Check Built Declarations steps after the tests
  • release.yaml: build-command: pnpm build && pnpm lint:dist
  • tsconfig.json: scripts/**/* is type-checked

Verification

Build pnpm lint:dist
6.18.0 (main) ❌ 81 × TS2503 in 48 of 204 files
This branch ✅ 204 files, no errors
  • pnpm lint, pnpm build and pnpm test (224/224) pass.
  • The guard was checked: it fails when the React global can't be found in @types/react.

After merging

  • Confirm the release produces 6.18.1.
  • Verify in ODC apps/web (tsc --noEmit -p .) with the published 6.18.1, or with a direct file: dependency. A file: tarball in the pnpm catalog isn't supported.

Separately, adding export as namespace React; to ODC's vendored react@19.x types would also fix the third-party bare React.* in @base-ui/react, which libui can't fix.

🤖 Generated with Claude Code

Closes issue #126

This branch has not been deployed

No deployments
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