Skip to content

fix: avoid walking ref props in styled mappings#344

Open
emmanuelchucks wants to merge 1 commit into
nativewind:mainfrom
emmanuelchucks:fix/styled-ref-dot-notation
Open

fix: avoid walking ref props in styled mappings#344
emmanuelchucks wants to merge 1 commit into
nativewind:mainfrom
emmanuelchucks:fix/styled-ref-dot-notation

Conversation

@emmanuelchucks

Copy link
Copy Markdown

Summary

Fixes a TypeScript performance issue where styled() can hang when wrapping components whose props include complex ref types, such as react-strict-dom elements.

StyledConfiguration currently computes dot-notation style targets from ComponentProps<C>. For components like html.div, that includes ref?: React.Ref<HTMLDivElement>. DotNotation then recursively walks into DOM element types through ref, which can make TypeScript hang.

This changes style-mapping target inference to use PropsWithoutRef<ComponentProps<C>>, while preserving ref on the returned styled component props.

Closes #343.

Reproduction

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

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" />;

Test plan

Ran locally:

yarn typecheck
yarn lint
yarn test --maxWorkers=2
yarn build
yarn example expo export --platform web

Also verified the react-strict-dom repro typechecks after the change.

Copilot AI review requested due to automatic review settings May 24, 2026 22:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Updates runtime type utilities to exclude ref from derived component props when used in style mapping and dot-notation types, avoiding ref being treated as a style-addressable prop.

Changes:

  • Import PropsWithoutRef from React and apply it to ComponentProps<C> in NativeStyleMapping usages.
  • Update ComponentPropsDotNotation to use PropsWithoutRef<ComponentProps<C>>.

Comment thread src/runtime.types.ts
Comment on lines 89 to 92
: NativeStyleMapping<
ResolveDotPath<T, ComponentProps<C>>,
ComponentProps<C>
PropsWithoutRef<ComponentProps<C>>
>;
Comment thread src/runtime.types.ts
Comment on lines 95 to +96
ResolveDotPath<T, ComponentProps<C>>,
ComponentProps<C>
PropsWithoutRef<ComponentProps<C>>
Comment thread src/runtime.types.ts
Comment on lines +88 to +91
? NativeStyleMapping<string, PropsWithoutRef<ComponentProps<C>>>
: NativeStyleMapping<
ResolveDotPath<T, ComponentProps<C>>,
ComponentProps<C>
PropsWithoutRef<ComponentProps<C>>
Comment thread src/runtime.types.ts
nativeStyleToProp?: NativeStyleMapping<
ResolveDotPath<T, ComponentProps<C>>,
ComponentProps<C>
PropsWithoutRef<ComponentProps<C>>
Comment thread src/runtime.types.ts

export type ComponentPropsDotNotation<C extends ReactComponent> = DotNotation<
ComponentProps<C>
PropsWithoutRef<ComponentProps<C>>
@danstepanov danstepanov added the deferred (post-5.0) Not required for the 5.0 latest release; revisit after label Jul 8, 2026
@danstepanov

Copy link
Copy Markdown
Member

Preemptive review to help triage for the 5.0 release, @marklawlor makes the final call.

The diagnosis in #343 is right. DotNotation enumerates ComponentProps including ref, and a DOM typed ref drags the whole DOM type graph into the walk. PropsWithoutRef stops it at the source, ref still works on the returned component, and it's type level only with zero runtime change. Applies cleanly to main. Not required to ship latest but a safe one file fix for a confirmed bug, easy merge now or in the first 5.x patch. Unrelated note while I was in here, StyledConfigurationObject passes ResolveDotPath's arguments in swapped order and only typechecks because the generic collapses to any, worth a separate look.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

deferred (post-5.0) Not required for the 5.0 latest release; revisit after

Projects

None yet

Development

Successfully merging this pull request may close these issues.

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

3 participants