Skip to content

Commit dc8b143

Browse files
authored
update types, turn on strict and noImplicitAny TS flags (#1893)
1 parent 62c28ac commit dc8b143

25 files changed

Lines changed: 242 additions & 255 deletions

common/styleguide.tsx

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
import * as HtmlElements from '@expo/html-elements';
22
import { TextProps } from '@expo/html-elements/build/primitives/Text';
33
import Link from 'next/link';
4-
import { ComponentType, PropsWithChildren, useContext, useState } from 'react';
5-
import { StyleSheet, TextStyle, View, useWindowDimensions, ViewStyle } from 'react-native';
4+
import { type ComponentType, type PropsWithChildren, useContext, useState } from 'react';
5+
import {
6+
StyleSheet,
7+
TextStyle,
8+
View,
9+
useWindowDimensions,
10+
ViewStyle,
11+
StyleProp,
12+
} from 'react-native';
613

714
import CustomAppearanceContext from '../context/CustomAppearanceContext';
815

@@ -87,16 +94,16 @@ type CustomTextProps = TextProps &
8794
const createTextComponent = (Element: ComponentType<TextProps>, textStyle?: TextStyles) => {
8895
const TextComponent = ({ children, style, id, numberOfLines }: CustomTextProps) => {
8996
const { isDark } = useContext(CustomAppearanceContext);
97+
98+
const elementStyle = Element?.displayName
99+
? StyleSheet.flatten(textStyles[Element.displayName as keyof typeof textStyles])
100+
: undefined;
101+
90102
return (
91103
<Element
92104
id={id}
93105
numberOfLines={numberOfLines}
94-
style={[
95-
textStyles[Element.displayName],
96-
textStyle,
97-
{ color: isDark ? colors.white : colors.black },
98-
style,
99-
]}>
106+
style={[elementStyle, textStyle, { color: isDark ? colors.white : colors.black }, style]}>
100107
{children}
101108
</Element>
102109
);
@@ -118,30 +125,22 @@ export const Caption = createTextComponent(HtmlElements.P, textStyles.caption);
118125
export const Label = createTextComponent(HtmlElements.P, textStyles.label);
119126

120127
type AProps = PropsWithChildren<{
121-
style?: TextStyles;
128+
style?: StyleProp<TextStyle>;
122129
target?: string;
123130
href: string;
124-
hoverStyle?: TextStyles;
125-
containerStyle?: ViewStyle;
131+
hoverStyle?: StyleProp<TextStyle>;
132+
containerStyle?: StyleProp<ViewStyle>;
126133
}>;
127134

128-
export const A = ({
129-
href,
130-
target,
131-
children,
132-
style,
133-
hoverStyle,
134-
containerStyle,
135-
...rest
136-
}: AProps) => {
135+
export function A({ href, target, children, style, hoverStyle, containerStyle, ...rest }: AProps) {
137136
const { isDark } = useContext(CustomAppearanceContext);
138137
const [isHovered, setIsHovered] = useState(false);
139138

140139
const linkStyles = getLinkStyles(isDark);
141140
const linkHoverStyles = getLinkHoverStyles();
142141

143142
if ((target === '_self' && !href.startsWith('#')) || href.startsWith('/')) {
144-
const passedStyle = Array.isArray(style) ? StyleSheet.flatten(style) : style;
143+
const passedStyle = StyleSheet.flatten(style);
145144
return (
146145
<Link
147146
href={href}
@@ -151,7 +150,7 @@ export const A = ({
151150
...linkStyles,
152151
...(passedStyle as any),
153152
...(isHovered && linkHoverStyles),
154-
...(isHovered && hoverStyle),
153+
...(isHovered && hoverStyle && StyleSheet.flatten(hoverStyle)),
155154
}}>
156155
{children}
157156
</Link>
@@ -174,18 +173,22 @@ export const A = ({
174173
</HtmlElements.A>
175174
</View>
176175
);
177-
};
176+
}
178177

179-
const getLinkStyles = (isDark: boolean) => ({
180-
color: isDark ? colors.white : colors.black,
181-
textDecorationColor: isDark ? colors.gray5 : colors.pewter,
182-
textDecorationLine: 'underline',
183-
fontFamily: 'inherit',
184-
});
178+
function getLinkStyles(isDark: boolean): TextStyle {
179+
return {
180+
color: isDark ? colors.white : colors.black,
181+
textDecorationColor: isDark ? colors.gray5 : colors.pewter,
182+
textDecorationLine: 'underline',
183+
fontFamily: 'inherit',
184+
};
185+
}
185186

186-
const getLinkHoverStyles = () => ({
187-
textDecorationColor: colors.primaryDark,
188-
});
187+
function getLinkHoverStyles(): TextStyle {
188+
return {
189+
textDecorationColor: colors.primaryDark,
190+
};
191+
}
189192

190193
export function HoverEffect({ children }: PropsWithChildren) {
191194
const [isHovered, setIsHovered] = useState(false);

components/Button.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { A } from '@expo/html-elements';
22
import { PropsWithChildren, useContext } from 'react';
3-
import { StyleSheet, TextStyle, Pressable } from 'react-native';
3+
import { StyleSheet, TextStyle, Pressable, StyleProp } from 'react-native';
44

55
import { colors, darkColors, HoverEffect, P } from '~/common/styleguide';
66
import CustomAppearanceContext from '~/context/CustomAppearanceContext';
@@ -9,7 +9,7 @@ type Props = PropsWithChildren & {
99
href?: string;
1010
onPress?: () => void;
1111
openInNewTab?: boolean;
12-
style?: TextStyle | TextStyle[];
12+
style?: StyleProp<TextStyle>;
1313
};
1414

1515
export function Button({ children, href, onPress, style, openInNewTab, ...rest }: Props) {

components/CheckBox.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import { useContext } from 'react';
2-
import { StyleSheet, View, ViewStyle } from 'react-native';
2+
import { StyleProp, StyleSheet, View, ViewStyle } from 'react-native';
33

44
import { colors, darkColors } from '~/common/styleguide';
55
import CustomAppearanceContext from '~/context/CustomAppearanceContext';
66

77
import { Check } from './Icons';
88

99
type Props = {
10-
style?: ViewStyle | ViewStyle[];
10+
style?: StyleProp<ViewStyle>;
1111
value?: boolean;
1212
color?: string;
1313
};

components/Filters/FilterButton.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export const FilterButton = ({
3636
];
3737

3838
const filterCount = Object.keys(query).reduce(
39-
(acc, q) => (params.includes(q) ? acc + 1 : acc),
39+
(acc, q) => (params.includes(q as keyof Query) ? acc + 1 : acc),
4040
0
4141
);
4242
const isFilterCount = !!filterCount;

components/Filters/ToggleLink.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { CheckBox } from '../CheckBox';
1111

1212
type Props = {
1313
query: Query;
14-
paramName: string;
14+
paramName: keyof Query;
1515
title: string;
1616
basePath?: string;
1717
};

components/Filters/helpers.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
export const FILTER_PLATFORMS = [
1+
import { Query } from '~/types';
2+
3+
type FilterParamsType = {
4+
param: keyof Query;
5+
title: string;
6+
};
7+
8+
export const FILTER_PLATFORMS: FilterParamsType[] = [
29
{
310
param: 'android',
411
title: 'Android',
@@ -29,7 +36,7 @@ export const FILTER_PLATFORMS = [
2936
},
3037
];
3138

32-
export const FILTER_REQUIRES_MAIN_SEARCH = [
39+
export const FILTER_REQUIRES_MAIN_SEARCH: FilterParamsType[] = [
3340
{
3441
param: 'isMaintained',
3542
title: 'Maintained',
@@ -40,7 +47,7 @@ export const FILTER_REQUIRES_MAIN_SEARCH = [
4047
},
4148
];
4249

43-
export const FILTER_STATUS = [
50+
export const FILTER_STATUS: FilterParamsType[] = [
4451
{
4552
param: 'newArchitecture',
4653
title: 'Supports New Architecture',
@@ -67,7 +74,7 @@ export const FILTER_STATUS = [
6774
},
6875
];
6976

70-
export const FILTER_COMPATIBILITY = [
77+
export const FILTER_COMPATIBILITY: FilterParamsType[] = [
7178
{
7279
param: 'expoGo',
7380
title: 'Works with Expo Go',

components/Filters/index.tsx

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -58,21 +58,21 @@ export function Filters({ query, style, basePath = '/' }: FiltersProps) {
5858
<Headline style={[styles.title, titleColor]}>Status</Headline>
5959
<View style={styles.optionsContainer}>
6060
{isMainSearch &&
61-
FILTER_REQUIRES_MAIN_SEARCH.map(platform => (
61+
FILTER_REQUIRES_MAIN_SEARCH.map(status => (
6262
<ToggleLink
63-
key={platform.param}
63+
key={status.param}
6464
query={pageQuery}
65-
paramName={platform.param}
66-
title={platform.title}
65+
paramName={status.param}
66+
title={status.title}
6767
basePath={basePath}
6868
/>
6969
))}
70-
{FILTER_STATUS.map(platform => (
70+
{FILTER_STATUS.map(status => (
7171
<ToggleLink
72-
key={platform.param}
72+
key={status.param}
7373
query={pageQuery}
74-
paramName={platform.param}
75-
title={platform.title}
74+
paramName={status.param}
75+
title={status.title}
7676
basePath={basePath}
7777
/>
7878
))}
@@ -82,12 +82,12 @@ export function Filters({ query, style, basePath = '/' }: FiltersProps) {
8282
<View style={[styles.wrappableContainer, isSmallScreen && { maxWidth: '100%' }]}>
8383
<Headline style={[styles.title, titleColor]}>Compatibility</Headline>
8484
<View style={styles.optionsContainer}>
85-
{FILTER_COMPATIBILITY.map(platform => (
85+
{FILTER_COMPATIBILITY.map(compatibility => (
8686
<ToggleLink
87-
key={platform.param}
87+
key={compatibility.param}
8888
query={pageQuery}
89-
paramName={platform.param}
90-
title={platform.title}
89+
paramName={compatibility.param}
90+
title={compatibility.title}
9191
basePath={basePath}
9292
/>
9393
))}

components/Footer.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import { FunctionComponent, SVGAttributes, createElement, useContext } from 'react';
1+
import { ComponentType, createElement, useContext } from 'react';
22
import { StyleSheet, View, ViewStyle } from 'react-native';
33

44
import { A, P, colors, darkColors, useLayout } from '~/common/styleguide';
55
import CustomAppearanceContext from '~/context/CustomAppearanceContext';
66

77
import ContentContainer from './ContentContainer';
88
import {
9+
IconProps,
910
Logo,
1011
PlatformAndroid,
1112
PlatformIOS,
@@ -21,7 +22,7 @@ type PlatformProps = {
2122
name: string;
2223
pkgName: string;
2324
url: string;
24-
Icon: FunctionComponent<SVGAttributes<SVGElement>>;
25+
Icon: ComponentType<IconProps>;
2526
style?: ViewStyle;
2627
};
2728

components/Library/UnmaintainedLabel.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Fragment, useContext } from 'react';
2-
import { StyleSheet, View } from 'react-native';
2+
import { StyleProp, StyleSheet, TextStyle, View } from 'react-native';
33

44
import { A, colors, darkColors, Label, useLayout } from '~/common/styleguide';
55
import CustomAppearanceContext from '~/context/CustomAppearanceContext';
@@ -15,7 +15,7 @@ function UnmaintainedLabel({ alternatives }: Props) {
1515
const { isDark } = useContext(CustomAppearanceContext);
1616
const { isSmallScreen } = useLayout();
1717

18-
const linkHoverStyle = isDark && { color: colors.secondary };
18+
const linkHoverStyle: StyleProp<TextStyle> = isDark && { color: colors.secondary };
1919
const contentColor = isDark ? darkColors.secondary : colors.gray5;
2020

2121
return (

components/Search.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const Search = ({ query, total }: Props) => {
2424
const [isInputFocused, setInputFocused] = useState(false);
2525
const [isFilterVisible, setFilterVisible] = useState(Object.keys(filterParams).length > 0);
2626
const [isApple, setIsApple] = useState<boolean | null>(null);
27-
const inputRef = useRef(null);
27+
const inputRef = useRef<TextInput>(null);
2828

2929
const { isSmallScreen } = useLayout();
3030
const { isDark } = useContext(CustomAppearanceContext);
@@ -79,7 +79,7 @@ const Search = ({ query, total }: Props) => {
7979
if (inputRef.current && event.key === 'Escape') {
8080
if (search) {
8181
event.preventDefault();
82-
inputRef.current.value = '';
82+
inputRef.current.clear();
8383
void Router.replace(
8484
urlWithQuery('/', {
8585
...query,

0 commit comments

Comments
 (0)