Skip to content

React 19 types: useScopedUI ref is not assignable to element refs #26

@Austin1serb

Description

@Austin1serb

Summary

useScopedUI exposes a ref type that breaks with newer React 19 typings when attached to specific elements like <div>.

Problem

In packages/core/src/index.ts, ScopedSetterFn.ref is exposed as a generic HTMLElement ref shape. Under newer React 19 type definitions, that is no longer assignable to refs on specific element types like HTMLDivElement.

This shows up as errors like:

Type 'ScopedRef | undefined' is not assignable to type 'Ref<HTMLDivElement> | undefined'.
Type 'RefObject<HTMLElement | null>' is not assignable to type 'RefObject<HTMLDivElement | null>'.

Repro

I hit this while upgrading the Vite fixture in this repo to a current stack:

  • react@19.2.4
  • react-dom@19.2.4
  • @types/react@19.2.14
  • @types/react-dom@19.2.3
  • vite@8.0.3
  • @vitejs/plugin-react@6.0.1

Then running:

  • pnpm --dir packages/core/__tests__/fixtures/vite run build

The build failed with type errors in the fixture where setScope.ref, setMobile.ref, and setOpen.ref were passed to <div ref={...}>.

Root cause

The scoped ref API is typed too broadly for newer React ref assignability rules.

A generic HTMLElement ref object is not safely assignable to HTMLDivElement, HTMLButtonElement, etc. React 19's typings are stricter here and correctly reject that mismatch.

Expected behavior

useScopedUI(...)[1].ref should be assignable to normal intrinsic element refs in React 19 projects without requiring casts in user code.

Suggested direction

Expose ref as a callback ref shape instead of a RefObject<HTMLElement> union.

A stable callback ref that accepts HTMLElement | null works cleanly with intrinsic element ref props and avoids the RefObject<HTMLElement> to RefObject<HTMLDivElement> incompatibility.

Why this matters

This is easy to hit for anyone upgrading to current React 19 typings, even if runtime behavior is fine. It turns a working API into a TypeScript error in normal usage.

Metadata

Metadata

Assignees

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