Skip to content

Commit e8fc025

Browse files
MatiPl01tjzel
andauthored
Migrate example app to the new TS api (#8152)
## Summary This PR migrates examples in out example app to the new TS types enabled via the [react-native-strict-api](https://reactnative.dev/docs/strict-typescript-api#opting-in) option in the tsconfig --------- Co-authored-by: Tomasz Żelawski <[email protected]>
1 parent 33258b0 commit e8fc025

File tree

20 files changed

+101
-98
lines changed

20 files changed

+101
-98
lines changed

.github/workflows/reanimated-static-checks.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@ jobs:
4545
run: yarn type:check
4646
- name: Check TypeScript types with React Native Strict API
4747
working-directory: ${{ env.PACKAGE_PATH }}
48-
# TODO - change to type:check:strict once the types in the example app are updated
49-
run: yarn type:check:strict:src
48+
run: yarn type:check:strict
5049
- name: Lint JavaScript
5150
working-directory: ${{ env.PACKAGE_PATH }}
5251
run: yarn lint:js

apps/common-app/src/apps/css/components/inputs/TabSelector.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
faChevronRight,
44
} from '@fortawesome/free-solid-svg-icons';
55
import { FontAwesomeIcon } from '@fortawesome/react-native-fontawesome';
6+
import type { ComponentRef } from 'react';
67
import { useEffect, useMemo } from 'react';
78
import { Pressable, StyleSheet, View } from 'react-native';
89
import Animated, {
@@ -34,7 +35,7 @@ function TabSelector<T extends string>({
3435
selectedTab,
3536
tabs,
3637
}: TabSelectorProps<T>) {
37-
const scrollViewRef = useAnimatedRef<Animated.ScrollView>();
38+
const scrollViewRef = useAnimatedRef<ComponentRef<Animated.ScrollView>>();
3839

3940
const containerWidth = useSharedValue(0);
4041
const tabWidths = useSharedValue<Array<number>>([]);

apps/common-app/src/apps/css/components/misc/ActionSheetDropdown.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Portal } from '@gorhom/portal';
2-
import type { PropsWithChildren, ReactNode } from 'react';
2+
import type { ComponentRef, PropsWithChildren, ReactNode } from 'react';
33
import { useRef, useState } from 'react';
44
import type { StyleProp, ViewStyle } from 'react-native';
55
import {
@@ -92,7 +92,7 @@ export default function ActionSheetDropdown({
9292
styleOptions,
9393
...contentProps
9494
}: ActionSheetDropdownProps): JSX.Element {
95-
const containerRef = useRef<View>(null);
95+
const containerRef = useRef<ComponentRef<typeof View>>(null);
9696
const insets = useSafeAreaInsets();
9797
const [{ isOpen, toggleMeasurements }, setState] = useState<DropdownState>({
9898
isOpen: false,
@@ -185,7 +185,10 @@ function DropdownContent({
185185
style,
186186
toggleMeasurements,
187187
}: DropdownContentProps): JSX.Element {
188-
const flattenedStyle = StyleSheet.flatten(style);
188+
// TODO - fix infinite type recursion or create a repro and report the issue
189+
// to the RN team. For now we are casting the type to any.
190+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
191+
const flattenedStyle = StyleSheet.flatten(style as any) as ViewStyle;
189192
const windowDimensions = Dimensions.get('window');
190193
const scrollRef = useAnimatedRef<Animated.ScrollView>();
191194
const scrollOffset = useScrollOffset(scrollRef);

apps/common-app/src/apps/css/examples/animations/screens/animatedProperties/base/appearance/transforms/relatedProperties/TransformOrigin.tsx

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -124,15 +124,18 @@ export default function TransformOrigin() {
124124
sections: [
125125
{
126126
description:
127-
'Single value specified in pixels (or as a number). It is applied only to the **x axis**. The second axis is set to `center` by default.',
127+
'Single value specified in pixels (or 3-value array). It is applied only to the **x axis**. The second axis is set to `center` by default.',
128128
examples: [
129129
{
130130
title: 'As a pixels string',
131131
transformOrigins: ['10px', '100px'],
132132
},
133133
{
134134
title: 'As a number',
135-
transformOrigins: [[-50], [100]],
135+
transformOrigins: [
136+
[-50, 0, 0],
137+
[100, 0, 0],
138+
],
136139
},
137140
],
138141
title: 'Single value',
@@ -148,8 +151,8 @@ export default function TransformOrigin() {
148151
{
149152
title: 'As a number',
150153
transformOrigins: [
151-
[120, -20],
152-
[-50, 60],
154+
[120, -20, 0],
155+
[-50, 60, 0],
153156
],
154157
},
155158
],
@@ -193,7 +196,7 @@ export default function TransformOrigin() {
193196
examples: [
194197
{
195198
title: 'Mixed values',
196-
transformOrigins: ['-75px', '50%', [-25], 'center'],
199+
transformOrigins: ['-75px', '50%', [-25, 0, 0], 'center'],
197200
},
198201
],
199202
title: 'Single value',
@@ -206,7 +209,7 @@ export default function TransformOrigin() {
206209
title: 'Mixed values',
207210
transformOrigins: [
208211
'-50px 50%',
209-
[50, 0],
212+
[50, 0, 0],
210213
'center bottom',
211214
'125% bottom',
212215
],

apps/common-app/src/apps/css/navigation/search/ExpandableHeaderScreen.tsx

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
1-
import type { Component } from 'react';
21
import { isValidElement, useEffect, useMemo } from 'react';
3-
import type {
4-
ScrollView,
5-
ScrollViewProps,
6-
StyleProp,
7-
ViewStyle,
8-
} from 'react-native';
2+
import type { ScrollViewProps, StyleProp, ViewStyle } from 'react-native';
93
import { StyleSheet, View } from 'react-native';
104
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
115
import type { AnimatedRef, WithSpringConfig } from 'react-native-reanimated';
@@ -40,9 +34,6 @@ export enum ExpandMode {
4034
AUTO = 'AUTO',
4135
}
4236

43-
type ScrollableComponent = Component<Pick<ScrollViewProps, 'onScroll'>> &
44-
Pick<ScrollView, 'getScrollableNode'>;
45-
4637
type ExpandableHeaderScreenProps = {
4738
HeaderComponent: // eslint-disable-next-line @typescript-eslint/no-explicit-any
4839
React.ComponentType<any> | React.ReactElement | null | undefined;
@@ -52,8 +43,7 @@ type ExpandableHeaderScreenProps = {
5243
| React.ReactNode
5344
| ((
5445
props: Pick<ScrollViewProps, 'onScroll'> & {
55-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
56-
ref: AnimatedRef<any>;
46+
ref: AnimatedRef;
5747
}
5848
) => React.ReactNode);
5949
onHeaderShowProgressChange?: (progress: number) => void;
@@ -66,7 +56,7 @@ export default function ExpandableHeaderScreen({
6656
onHeaderShowProgressChange,
6757
children,
6858
}: ExpandableHeaderScreenProps) {
69-
const scrollableRef = useAnimatedRef<ScrollableComponent>();
59+
const scrollableRef = useAnimatedRef();
7060
const offsetY = useSharedValue(0);
7161
const headerHeight = useSharedValue(IS_WEB ? 72 : 0);
7262
const translateY = useSharedValue(IS_WEB ? 72 : 0);

apps/common-app/src/apps/css/navigation/search/SearchFilters.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { faChevronRight } from '@fortawesome/free-solid-svg-icons';
22
import { FontAwesomeIcon } from '@fortawesome/react-native-fontawesome';
3+
import type { ComponentRef } from 'react';
34
import { Fragment, useEffect, useMemo, useRef } from 'react';
45
import { Pressable, ScrollView, StyleSheet, View } from 'react-native';
56

@@ -26,7 +27,7 @@ export default function SearchFilters({
2627
queryResults,
2728
setCurrentFilter,
2829
}: SearchFiltersProps) {
29-
const scrollRef = useRef<ScrollView>(null);
30+
const scrollRef = useRef<ComponentRef<typeof ScrollView>>(null);
3031

3132
useEffect(() => {
3233
scrollRef.current?.scrollToEnd({ animated: true });

apps/common-app/src/apps/reanimated/examples/FilterExample.tsx

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ export default function FilterExample() {
3939
return { filter: [{ contrast: sv.value * 3 }] };
4040
});
4141

42-
// @ts-expect-error TODO: call processColor automatically
42+
// @ts-ignore - number returned by the processColor function is not assignable
43+
// to the color property without react-native-strict-api enabled
4344
const dropShadow = useAnimatedStyle(() => {
4445
return {
4546
filter: [
@@ -48,6 +49,7 @@ export default function FilterExample() {
4849
offsetX: sv.value * 10,
4950
offsetY: sv.value * 10,
5051
standardDeviation: sv.value * 10,
52+
// TODO: call processColor automatically
5153
color: processColor(
5254
interpolateColor(sv.value, [0, 1], ['red', 'blue'])
5355
),
@@ -90,7 +92,7 @@ export default function FilterExample() {
9092
<Text>brightness</Text>
9193
<Animated.Image
9294
source={balloonsImage}
93-
// @ts-expect-error TODO: fix types
95+
// @ts-ignore
9496
style={brightness}
9597
width={80}
9698
height={80}
@@ -99,7 +101,7 @@ export default function FilterExample() {
99101
<Text>opacity</Text>
100102
<Animated.Image
101103
source={balloonsImage}
102-
// @ts-expect-error TODO: fix types
104+
// @ts-ignore
103105
style={opacity}
104106
width={80}
105107
height={80}
@@ -108,7 +110,7 @@ export default function FilterExample() {
108110
<Text>blur (only Android)</Text>
109111
<Animated.Image
110112
source={balloonsImage}
111-
// @ts-expect-error TODO: fix types
113+
// @ts-ignore
112114
style={blur}
113115
width={80}
114116
height={80}
@@ -117,7 +119,7 @@ export default function FilterExample() {
117119
<Text>contrast (only Android)</Text>
118120
<Animated.Image
119121
source={balloonsImage}
120-
// @ts-expect-error TODO: fix types
122+
// @ts-ignore
121123
style={contrast}
122124
width={80}
123125
height={80}
@@ -126,7 +128,7 @@ export default function FilterExample() {
126128
<Text>dropShadow (only Android)</Text>
127129
<Animated.Image
128130
source={balloonsImage}
129-
// @ts-expect-error TODO: fix types
131+
// @ts-ignore
130132
style={dropShadow}
131133
width={80}
132134
height={80}
@@ -135,7 +137,7 @@ export default function FilterExample() {
135137
<Text>grayscale (only Android)</Text>
136138
<Animated.Image
137139
source={balloonsImage}
138-
// @ts-expect-error TODO: fix types
140+
// @ts-ignore
139141
style={grayscale}
140142
width={80}
141143
height={80}
@@ -144,7 +146,7 @@ export default function FilterExample() {
144146
<Text>hueRotate (only Android)</Text>
145147
<Animated.Image
146148
source={balloonsImage}
147-
// @ts-expect-error TODO: fix types
149+
// @ts-ignore
148150
style={hueRotate}
149151
width={80}
150152
height={80}
@@ -153,7 +155,7 @@ export default function FilterExample() {
153155
<Text>invert (only Android)</Text>
154156
<Animated.Image
155157
source={balloonsImage}
156-
// @ts-expect-error TODO: fix types
158+
// @ts-ignore
157159
style={invert}
158160
width={80}
159161
height={80}
@@ -162,7 +164,7 @@ export default function FilterExample() {
162164
<Text>sepia (only Android)</Text>
163165
<Animated.Image
164166
source={balloonsImage}
165-
// @ts-expect-error TODO: fix types
167+
// @ts-ignore
166168
style={sepia}
167169
width={80}
168170
height={80}
@@ -171,7 +173,7 @@ export default function FilterExample() {
171173
<Text>saturate (only Android)</Text>
172174
<Animated.Image
173175
source={balloonsImage}
174-
// @ts-expect-error TODO: fix types
176+
// @ts-ignore
175177
style={saturate}
176178
width={80}
177179
height={80}

apps/common-app/src/apps/reanimated/examples/LightBoxExample.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import '../types';
22

33
import { useHeaderHeight } from '@react-navigation/elements';
4-
import type { RefObject } from 'react';
4+
import type { ComponentRef, RefObject } from 'react';
55
import React, { useEffect, useRef, useState } from 'react';
66
import {
77
Dimensions,
@@ -52,7 +52,7 @@ type ActiveExampleImage = {
5252
};
5353

5454
type onItemPressFn = (
55-
imageRef: RefObject<Image | null>,
55+
imageRef: ComponentRef<typeof Image>,
5656
item: ExampleImage,
5757
sv: SharedValue<number>
5858
) => void;
@@ -79,7 +79,7 @@ type ListItemProps = {
7979
};
8080

8181
function ListItem({ item, index, onPress }: ListItemProps) {
82-
const ref = useRef<Image>(null);
82+
const ref = useRef<ComponentRef<typeof Image>>(null);
8383
const opacity = useSharedValue(1);
8484

8585
const containerStyle = {
@@ -98,7 +98,7 @@ function ListItem({ item, index, onPress }: ListItemProps) {
9898
return (
9999
<TouchableWithoutFeedback
100100
style={containerStyle}
101-
onPress={() => onPress(ref, item, opacity)}>
101+
onPress={() => ref.current && onPress(ref.current, item, opacity)}>
102102
<AnimatedImage ref={ref} source={{ uri: item.uri }} style={styles} />
103103
</TouchableWithoutFeedback>
104104
);
@@ -246,11 +246,11 @@ export default function LightBoxExample() {
246246
);
247247

248248
function onItemPress(
249-
imageRef: RefObject<Image | null>,
249+
imageRef: ComponentRef<typeof Image>,
250250
item: ExampleImage,
251251
sv: SharedValue<number>
252252
) {
253-
imageRef.current?.measure?.((_x, _y, width, height, pageX, pageY) => {
253+
imageRef.measure?.((_x, _y, width, height, pageX, pageY) => {
254254
if (width === 0 && height === 0) {
255255
return;
256256
}

apps/common-app/src/apps/reanimated/examples/RuntimeTests/ReJest/types.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,13 @@ export enum ComparisonMode {
8888

8989
export type LockObject = { lock: boolean };
9090

91-
export type OperationUpdate = StyleProps | AnimatedStyle<Record<string, unknown>> | Record<string, unknown>;
91+
type Writable<T> = {
92+
-readonly [P in keyof T]: T[P];
93+
};
94+
95+
export type OperationUpdate = Writable<
96+
StyleProps | AnimatedStyle<Writable<Record<string, unknown>>> | Writable<Record<string, unknown>>
97+
>;
9298

9399
export interface Operation {
94100
tag?: number;

apps/common-app/src/apps/reanimated/examples/RuntimeTests/tests/animations/withTiming/colors.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@ const ColorComponent = ({ color1, color2 }: { color1: string | number; color2: s
1515
const refActive = useTestRef(COMPONENT_REF_ACTIVE);
1616
const refPassive = useTestRef(COMPONENT_REF_PASSIVE);
1717

18-
// @ts-expect-error number is not a valid color
18+
// @ts-ignore - number is not a valid color without react-native-strict-api enabled
1919
const styleActive = useAnimatedStyle(() => {
2020
return {
2121
backgroundColor: withDelay(100, withTiming(colorActiveSV.value, { duration: 400 })),
2222
};
2323
});
2424

25-
// @ts-expect-error number is not a valid color
25+
// @ts-ignore - number is not a valid color without react-native-strict-api enabled
2626
const stylePassive = useAnimatedStyle(() => {
2727
return {
2828
backgroundColor: colorPassiveSV.value,

0 commit comments

Comments
 (0)