Skip to content

compat.native props type omits ref, though the runtime supports it #509

Description

@samgilmore-zr

Summary

compat.native's published props type (StrictPropsOnlyCompat in compat.d.ts) does not include ref, so TypeScript rejects:

<compat.native as="div" ref={ref} style={styles.x}>
  {(nativeProps) => <Pressable {...nativeProps} />}
</compat.native>

At runtime, refs work: the strict components destructure ref from props (React 19 ref-as-prop), wrap it via useStrictDOMElement, and fold it into nativeProps.ref before invoking function children — so the caller's ref receives the same DOM-emulation surface as html.* elements provide.

Details

html.d.ts re-adds ref per element with the Omit<StrictReactDOMProps, 'ref'> & { ref?: React.Ref<HTMLDivElement> } pattern, but compat.d.ts's StrictPropsOnlyCompat never got the same treatment:

type StrictPropsOnlyCompat<T> = Omit<
  StrictProps,
  keyof ({ as?: ...; children: (nativeProps: T) => React.ReactNode })
> & {
  as?: 'div' | 'img' | 'input' | 'span' | 'textarea';
  children: (nativeProps: T) => React.ReactNode;
};

Use case

We rebuilt our cross-platform Pressable primitive on compat.native so a single RNPressable IS the styled node (fixing shrink-wrapped touch targets from nesting an unstyled Pressable inside a styled html.div). Forwarding the component's ref requires a cast today:

const CompatNative = compat.native as unknown as React.ComponentType<{ ref?: React.Ref<HTMLDivElement>; ... }>;

Proposal

Add ref to StrictPropsOnlyCompat, ideally typed per the as element like the html.* declarations.

Version: react-strict-dom 0.0.55, React 19, React Native 0.85.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    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