chore: [TS] Transform TouchableHighlight from class to ForwardRef component (#44038)

Summary:
If you check the source of truth `packages/react-native/Libraries/Components/Touchable/TouchableHighlight.js` I'll find that `TouchableHighlight` is a result of `React.forwardRef(...)` :

https://github.com/facebook/react-native/blob/44d59ea6f9a1705487314e33de52f7056651ba25/packages/react-native/Libraries/Components/Touchable/TouchableHighlight.js#L382-L391

So the TS type isn't correct : (

```tsx
<TouchableHighlight ref={ref => {   }} />
//                     ^^^ ref should be a `View` (but now it's `TouchableHighlight`)
```

 ---

**Breaking  changes**

As `TouchableHighlight` isn't class anymore it can't be used as value & type

```tsx
import {TouchableHighlight} from 'react-native';
const ref = useRef<TouchableHighlight>();
//                ^^^ TS2749: TouchableHighlight refers to a value, but is being used as a type here.
//                            Did you mean typeof TouchableHighlight?
```

**Recommend solution:** use build-in react type `React.ElementRef`

```diff
-const ref = useRef<TouchableHighlight>();
+const ref = useRef<React.ElementRef<typeof TouchableHighlight>>();
```

Also, it possible to use `View` as type:

```diff
-const ref = useRef<TouchableHighlight>();
+const ref = useRef<View>();
```

## Changelog:

[GENERAL] [BREAKING] - [Typescript] Transform TouchableHighlight from JS class to ForwardRef component

Pull Request resolved: https://github.com/facebook/react-native/pull/44038

Test Plan: See: `packages/react-native/types/__typetests__/index.tsx`

Reviewed By: NickGerleman

Differential Revision: D56015309

Pulled By: dmytrorykun

fbshipit-source-id: fee346536787a5921626ed69a4c01da2b599dc2f
This commit is contained in:
D N
2024-04-11 14:21:55 -07:00
committed by Facebook GitHub Bot
parent 3d00549399
commit 401f2fbb14
2 changed files with 31 additions and 10 deletions
@@ -8,12 +8,9 @@
*/
import type * as React from 'react';
import {Constructor} from '../../../types/private/Utilities';
import {TimerMixin} from '../../../types/private/TimerMixin';
import {NativeMethods} from '../../../types/public/ReactNativeTypes';
import {ColorValue, StyleProp} from '../../StyleSheet/StyleSheet';
import {ViewStyle} from '../../StyleSheet/StyleSheetTypes';
import {TouchableMixin} from './Touchable';
import {View} from '../../Components/View/View';
import {TouchableWithoutFeedbackProps} from './TouchableWithoutFeedback';
/**
@@ -60,9 +57,6 @@ export interface TouchableHighlightProps extends TouchableWithoutFeedbackProps {
*
* @see https://reactnative.dev/docs/touchablehighlight
*/
declare class TouchableHighlightComponent extends React.Component<TouchableHighlightProps> {}
declare const TouchableHighlightBase: Constructor<NativeMethods> &
Constructor<TimerMixin> &
Constructor<TouchableMixin> &
typeof TouchableHighlightComponent;
export class TouchableHighlight extends TouchableHighlightBase {}
export const TouchableHighlight: React.ForwardRefExoticComponent<
React.PropsWithoutRef<TouchableHighlightProps> & React.RefAttributes<View>
>;
@@ -106,6 +106,7 @@ import {
TextStyle,
TouchableNativeFeedback,
TouchableOpacity,
TouchableHighlight,
TouchableWithoutFeedback,
UIManager,
View,
@@ -484,6 +485,32 @@ function TouchableTest() {
}
}
export class TouchableHighlightTest extends React.Component {
buttonRef = React.createRef<React.ElementRef<typeof TouchableHighlight>>();
render() {
return (
<>
<TouchableHighlight ref={this.buttonRef} />
<TouchableHighlight
ref={ref => {
ref?.focus();
ref?.blur();
ref?.measure(
(x, y, width, height, pageX, pageY): number =>
x + y + width + height + pageX + pageY,
);
ref?.measureInWindow(
(x, y, width, height): number => x + y + width + height,
);
ref?.setNativeProps({focusable: false});
}}
/>
</>
);
}
}
export class TouchableOpacityTest extends React.Component {
buttonRef = React.createRef<React.ElementRef<typeof TouchableOpacity>>();