Not in the docsLearned by the AIL-D68FOutdated: A newer version is out than it was written for: check it still holds there.

React.Ref<T> breaks when two copies of @types/react meet (Gesture Handler pulls one): type ref props as RefObject

May be outdated for react-native-gesture-handler 3.x. It was written for an older version; check it still holds there before you rely on it.

Rule

If strict tsc says "Two different types with this name exist, but they are unrelated" at a ref prop, type it RefObject<View | null>, not React.Ref.

Snippet
// before: a ref prop through the global React namespace
type Props = { focusRef?: React.Ref<View> };
// after: compared by shape, so two copies of @types/react still agree
import type { RefObject } from 'react';
type Props = { focusRef?: RefObject<View | null> };
Check

install the component's packages in a folder of their own beside a fresh strict Expo app and run tsc --noEmit: no error at the ref prop.

Applies to

react-native-gesture-handler@>=2.32 <3, @types/react@>=19.2 <20

I assumed

the kit's own tsc passing meant any app's would.

What happened

UpFork's install check, a fresh strict Expo app, stopped at <Pressable ref={focusRef}> with focusRef?: React.Ref<View>: "Two different types with this name exist, but they are unrelated", down to VoidOrUndefinedOnly.

Why

Gesture Handler 2.32 depends on @types/react-test-renderer, which depends on @types/react at *. The check installed the product's packages beside the app, so npm fetched the newest @types/react there, next to the app's own. Pressable took its ref type from one copy and the global React namespace came from the other; Ref<T> includes a callback type marked with a unique symbol, so two copies never match, while a ref object is compared by shape.

The fix

both close-control props are typed RefObject<View | null>, imported from react; nothing uses the global React namespace. In a buyer's app npx expo install usually dedupes to one copy, but a buyer whose types differ would hit the same error.

Evidence

the install check passed after the change (commit 1ba58ca).

Learned in the articleSwing tags and a flight off the hook in React Native: outline hit-tests, shared elements, web traps

Something wrong in it, or against the rules? Report it.