Skip to content

react-aria-components: ButtonProps exposes @react-types/shared types not re-exported, causing TS2883 in composite/project-reference builds #10166

@icopp

Description

@icopp

Provide a general summary of the issue here

react-aria-components exposes FocusableElement, HoverEvent, and KeyboardEvent (from @react-types/shared) as part of the structural type of ButtonProps, but does not re-export them from its own package. In TypeScript monorepos using project references (composite: true, declaration: true), any file that re-exports or infers a type involving ButtonProps produces TS2883 errors because TypeScript must emit declaration files that name those types, yet has no portable way to import them — @react-types/shared is a transitive dependency, not a direct one, and TypeScript cannot write a stable import for it in emitted .d.ts files.

🤔 Expected Behavior?

react-aria-components should re-export all types from @react-types/shared that appear in its public API surface (e.g. as part of ButtonProps). Consumers using composite: true + declaration: true should be able to build without TS2883 errors, without needing to add @react-types/shared as a direct dependency.

😯 Current Behavior

In any TypeScript monorepo with project references, files that expose types derived from ButtonProps (e.g. a wrapper component, or Storybook CSF stories with inferred types) emit:

error TS2883: The inferred type of 'Button' cannot be named without a reference to
'FocusableElement' from '.../@react-types/shared'. This is likely not portable.
A type annotation is necessary.

error TS2883: The inferred type of 'Button' cannot be named without a reference to
'HoverEvent' from '.../@react-types/shared'. This is likely not portable.
A type annotation is necessary.

error TS2883: The inferred type of 'Button' cannot be named without a reference to
'KeyboardEvent' from '.../@react-types/shared'. This is likely not portable.
A type annotation is necessary.

The three types surface because:

  • FocusableElementPressEvents.onClick?: (e: MouseEvent<FocusableElement>) => void (via AriaButtonPropsButtonPropsPressEvents)
  • HoverEventHoverEvents.onHoverStart/End?: (e: HoverEvent) => void (direct extends on react-aria-components ButtonProps)
  • KeyboardEvent (@react-types/shared, not DOM) — KeyboardEvents.onKeyDown/Up?: (e: KeyboardEvent) => void (via AriaButtonPropsButtonPropsFocusablePropsKeyboardEvents)

None of these types are re-exported from react-aria-components' root, so TypeScript cannot name them through a direct dependency.

💁 Possible Solution

Add the three types to the existing @react-types/shared re-export line in dist/types/exports/index.d.ts:

-export type { RangeValue, ValidationResult, RouterConfig } from '@react-types/shared';
+export type { RangeValue, ValidationResult, RouterConfig, FocusableElement, HoverEvent, KeyboardEvent } from '@react-types/shared';

This is consistent with the existing pattern of re-exporting @react-types/shared types that are part of the public API. We confirmed locally (via a pnpm patch) that this one-line change resolves all TS2883 errors related to ButtonProps.

There may be other TS2883 errors we didn't run into related to other types that also need to be re-exported. The better solution may be to simply re-export all types from @react-types/shared.

🔦 Context

This affects any TypeScript monorepo using project references where a package wraps or re-exports React Aria Components and emits declaration files. It is not specific to any particular package manager or symlink resolution strategy — the issue is that TypeScript needs a stable, direct-dependency import path for every type that appears in emitted .d.ts files, and these three types currently have none through react-aria-components.

🖥️ Steps to Reproduce

  1. Create a TypeScript monorepo with project references (two packages: pkg-a and pkg-b)
  2. Add react-aria-components as a direct dependency of pkg-a
  3. In pkg-a/tsconfig.json: set "composite": true, "declaration": true
  4. In pkg-a, create a component that wraps Button from react-aria-components and exports its props type (or any file that infers and exports a type involving ButtonProps)
  5. Run tsc -b from the repo root

Expected: build succeeds
Actual: TS2883 on every exported symbol whose inferred type involves FocusableElement, HoverEvent, or KeyboardEvent from @react-types/shared

Version

react-aria-components@1.18.0, @react-types/shared@3.35.0

What browsers are you seeing the problem on?

N/A — TypeScript tooling / build issue, not a browser runtime issue.

What operating system are you using?

macOS (confirmed), likely reproducible on all platforms.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions