You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix ref type compatibility for builtin components (#56673)
Summary:
Fix `useRef` and `forwardRef` backcompat when migrating to React Native's generated TypeScript types (Strict TypeScript API).
Previously this was an awkward breaking change: https://reactnative.dev/docs/strict-typescript-api#some-core-components-are-now-function-components-instead-of-class-components
```diff
- const ref = useRef<View>(null);
+ const ref = useRef<React.ComponentRef<typeof View>>(null);
```
After this diff, no workaround will be required.
**Problem detail**
In our Flow source code, built-in components like `View` and `TextInput` are function components rather than classes. This differs from the previous manual `.d.ts` files which defined each component as a class.
In TypeScript, a class name serves as both a value (the constructor) and a type (the instance), so patterns like `useRef<View>()` work. However, with function components, the name is only a value (the function signature) making `useRef<View>()` resolve to a ref holding the function itself, not the native element.
**The fix**: Add companion type aliases alongside each component's value export. TypeScript's declaration merging makes the component name simultaneously a value (for JSX) and a type (for refs).
```diff
// Before — required workaround
- const ref = useRef<View>(null);
+ const ref = useRef<React.ComponentRef<typeof View>>(null);
ref.current?.measure(...);
- const inputRef = useRef<TextInput>(null);
+ const inputRef = useRef<React.ComponentRef<typeof TextInput>>(null);
inputRef.current?.focus();
// After — original patterns work as-is
const ref = useRef<View>(null); // View as a type = HostInstance
ref.current?.measure(...); // HostInstance has measure()
const inputRef = useRef<TextInput>(null); // TextInput as a type = TextInputInstance
inputRef.current?.focus(); // TextInputInstance has focus()
```
Changelog:
[General][Fixed] - Add companion instance type aliases for built-in components, preserving `useRef<Component>` patterns under the Strict TypeScript API
Differential Revision: D103601923
0 commit comments