Skip to content

TypeScript hangs when styled() wraps components with complex ref props #343

Open

Description

@emmanuelchucks

Before submitting a new issue

  • I tested using the latest version of the library, as the bug might be already fixed.
  • I tested using a supported version of react native.
  • I checked for possible duplicate issues, with possible answers.

Bug summary

styled() can cause TypeScript to hang when wrapping components whose props include complex ref types, such as react-strict-dom elements.

Minimal example:

import { html } from "react-strict-dom";
import { styled } from "react-native-css";

export const StyledDiv = styled(html.div, { className: "style" });

export const element = <StyledDiv className="p-4" />;

What I found

The issue appears to come from StyledConfiguration computing dot-notation style targets from:

DotNotation<ComponentProps<C>>

For html.div, ComponentProps<C> includes:

ref?: React.Ref<HTMLDivElement>

DotNotation then recursively walks into the ref type, then into HTMLDivElement, which expands into a large recursive DOM type graph.

I verified locally that:

  • ComponentProps<typeof html.div> typechecks quickly.
  • DotNotation<Pick<Props, "style">> typechecks quickly.
  • DotNotation<Pick<Props, "ref">> hangs.
  • styled(html.div, { className: "style" }) hangs before the fix.

Library version

3.0.7

Environment info

Node: 24.13.0
TypeScript: 5.9.2
react-native-css: 3.0.7
react-strict-dom: 0.0.55
react: 19.1.0
react-native: 0.81.4

Steps to reproduce

  1. Clone the repro repository.
  2. Install dependencies.
  3. Run npm run typecheck.

Reproducible example repository

https://github.com/emmanuelchucks/react-native-css-styled-rsd-ref-repro

Possible fix

Using PropsWithoutRef<ComponentProps<C>> for style-mapping target inference avoids walking ref, while still preserving ref on the returned styled component props.

Conceptually:

DotNotation<PropsWithoutRef<ComponentProps<C>>>

instead of:

DotNotation<ComponentProps<C>>

Activity

  1. github-actions commented on May 24, 2026

    @github-actions

    🤖 Auto-triage

    Status: CONFIRMED
    Type: bug
    Version: v5

    Findings

    Verified by code inspection at src/runtime.types.ts:121-123: ComponentPropsDotNotation is defined as DotNotation<ComponentProps<C>>, which (as the reporter correctly diagnosed) recurses into the ref field of components like react-strict-dom's html.div, expanding into the full DOM type graph and causing TypeScript to hang. The reporter's proposed fix — wrapping with PropsWithoutRef<...> — is sound and targeted: it avoids walking the ref type while keeping ref intact on the returned styled component's outer props.

    What I tested

    • Read CLAUDE.md, DEVELOPMENT.md, CONTRIBUTING.md for context.
    • Inspected src/runtime.types.ts to confirm ComponentPropsDotNotation definition matches the reporter's description.
    • Confirmed DotNotation is imported from react-native-css/utilities and applied to the full ComponentProps<C>.
    • Did not run the external repro repo (per triage policy, untrusted input not executed).
    • This bug is not Jest-reproducible — it is a TypeScript type-checking performance issue, not a compiler/runtime defect.

    Next steps

    • Apply the suggested change at src/runtime.types.ts:121-123 (and any other internal use of DotNotation<ComponentProps<C>>) to use PropsWithoutRef<ComponentProps<C>>.
    • Grep for any other recursive-into-ref hotspots in src/utilities/ and src/runtime.types.ts to make sure no other path triggers the same hang.
    • Consider adding a tsd/expect-type style test or a small TypeScript benchmark fixture to guard against regression — though this isn't easily covered by Jest.

    This is an automated triage. See auto-triage.yml.

  2. added
    auto-triagedIssue has been automatically triaged by the auto-triage workflow
    bugSomething isn't working
    confirmedBug reproduced and confirmed by triage
    on May 24, 2026
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

    auto-triagedIssue has been automatically triaged by the auto-triage workflowbugSomething isn't workingconfirmedBug reproduced and confirmed by triagedeferred (post-5.0)Not required for the 5.0 latest release; revisit after

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions