fix: avoid walking ref props in styled mappings#344
Conversation
There was a problem hiding this comment.
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
PropsWithoutReffrom React and apply it toComponentProps<C>inNativeStyleMappingusages. - Update
ComponentPropsDotNotationto usePropsWithoutRef<ComponentProps<C>>.
| : NativeStyleMapping< | ||
| ResolveDotPath<T, ComponentProps<C>>, | ||
| ComponentProps<C> | ||
| PropsWithoutRef<ComponentProps<C>> | ||
| >; |
| ResolveDotPath<T, ComponentProps<C>>, | ||
| ComponentProps<C> | ||
| PropsWithoutRef<ComponentProps<C>> |
| ? NativeStyleMapping<string, PropsWithoutRef<ComponentProps<C>>> | ||
| : NativeStyleMapping< | ||
| ResolveDotPath<T, ComponentProps<C>>, | ||
| ComponentProps<C> | ||
| PropsWithoutRef<ComponentProps<C>> |
| nativeStyleToProp?: NativeStyleMapping< | ||
| ResolveDotPath<T, ComponentProps<C>>, | ||
| ComponentProps<C> | ||
| PropsWithoutRef<ComponentProps<C>> |
|
|
||
| export type ComponentPropsDotNotation<C extends ReactComponent> = DotNotation< | ||
| ComponentProps<C> | ||
| PropsWithoutRef<ComponentProps<C>> |
|
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. |
Summary
Fixes a TypeScript performance issue where
styled()can hang when wrapping components whose props include complexreftypes, such asreact-strict-domelements.StyledConfigurationcurrently computes dot-notation style targets fromComponentProps<C>. For components likehtml.div, that includesref?: React.Ref<HTMLDivElement>.DotNotationthen recursively walks into DOM element types throughref, which can make TypeScript hang.This changes style-mapping target inference to use
PropsWithoutRef<ComponentProps<C>>, while preservingrefon the returned styled component props.Closes #343.
Reproduction
Minimal repro: https://github.com/emmanuelchucks/react-native-css-styled-rsd-ref-repro
Test plan
Ran locally:
Also verified the
react-strict-domrepro typechecks after the change.