Skip to content

Commit

Permalink
Merge pull request #40627 from ZhenjaHorbach/remove-unnecessary-ts-ex…
Browse files Browse the repository at this point in the history
…pect-error

Check and remove unnecessary @ts-expect-error suppressions
  • Loading branch information
grgia authored May 16, 2024
2 parents 5bfa295 + ef878d4 commit 4499fa2
Show file tree
Hide file tree
Showing 54 changed files with 2,042 additions and 2,206 deletions.
2 changes: 1 addition & 1 deletion .github/libs/sanitizeStringForJSONParse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const replacer = (str: string): string =>
* Solution partly taken from SO user Gabriel Rodríguez Flores 🙇
* https://stackoverflow.com/questions/52789718/how-to-remove-special-characters-before-json-parse-while-file-reading
*/
const sanitizeStringForJSONParse = (inputString: string): string => {
const sanitizeStringForJSONParse = (inputString: string | number | boolean | null | undefined): string => {
if (typeof inputString !== 'string') {
throw new TypeError('Input must me of type String');
}
Expand Down
4 changes: 1 addition & 3 deletions __mocks__/@react-navigation/native/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ import {useIsFocused as realUseIsFocused, useTheme as realUseTheme} from '@react
// We only want these mocked for storybook, not jest
const useIsFocused: typeof realUseIsFocused = process.env.NODE_ENV === 'test' ? realUseIsFocused : () => true;

// @ts-expect-error as we're mocking this function
const useTheme: typeof realUseTheme = process.env.NODE_ENV === 'test' ? realUseTheme : () => ({});
const useTheme = process.env.NODE_ENV === 'test' ? realUseTheme : () => ({});

export * from '@react-navigation/core';
export * from '@react-navigation/native';
export {useIsFocused, useTheme};
4 changes: 3 additions & 1 deletion src/Expensify.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ type ExpensifyOnyxProps = {

type ExpensifyProps = ExpensifyOnyxProps;

const SplashScreenHiddenContext = React.createContext({});
type SplashScreenHiddenContextType = {isSplashHidden?: boolean};

const SplashScreenHiddenContext = React.createContext<SplashScreenHiddenContextType>({});

function Expensify({
isCheckingPublicRoom = true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ function BaseAnchorForAttachmentsOnly({style, source = '', displayName = '', dow
}}
onPressIn={onPressIn}
onPressOut={onPressOut}
// @ts-expect-error TODO: Remove this once ShowContextMenuContext (https://github.com/Expensify/App/issues/24980) is migrated to TypeScript.
onLongPress={(event) => showContextMenuForReport(event, anchor, report.reportID, action, checkIfContextMenuActive, ReportUtils.isArchivedRoom(report))}
onLongPress={(event) => showContextMenuForReport(event, anchor, report?.reportID ?? '', action, checkIfContextMenuActive, ReportUtils.isArchivedRoom(report))}
shouldUseHapticsOnLongPress
accessibilityLabel={displayName}
role={CONST.ROLE.BUTTON}
Expand Down
1 change: 0 additions & 1 deletion src/components/PDFThumbnail/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
// @ts-expect-error - This line imports a module from 'pdfjs-dist' package which lacks TypeScript typings.
import pdfWorkerSource from 'pdfjs-dist/legacy/build/pdf.worker';
import React, {useMemo} from 'react';
import {View} from 'react-native';
Expand Down
2 changes: 1 addition & 1 deletion src/components/TabSelector/TabSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ function TabSelector({state, navigation, onTabPress = () => {}, position}: TabSe
return position.interpolate({
inputRange,
outputRange: inputRange.map((i) => (affectedTabs.includes(tabIndex) && i === tabIndex ? theme.border : theme.appBG)),
});
}) as unknown as Animated.AnimatedInterpolation<string>;
}
return theme.border;
},
Expand Down
1 change: 0 additions & 1 deletion src/hooks/useAutoFocusInput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ export default function useAutoFocusInput(): UseAutoFocusInput {
const [isInputInitialized, setIsInputInitialized] = useState(false);
const [isScreenTransitionEnded, setIsScreenTransitionEnded] = useState(false);

// @ts-expect-error TODO: Remove this when Expensify.js is migrated.
const {isSplashHidden} = useContext(Expensify.SplashScreenHiddenContext);

const inputRef = useRef<TextInput | null>(null);
Expand Down
1 change: 0 additions & 1 deletion src/hooks/useTabNavigatorFocus/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ function useTabNavigatorFocus({tabIndex}: UseTabNavigatorFocusParams): boolean {
// We need to get the position animation value on component initialization to determine
// if the tab is focused or not. Since it's an Animated.Value the only synchronous way
// to retrieve the value is to use a private method.
// @ts-expect-error -- __getValue is a private method
// eslint-disable-next-line no-underscore-dangle
const initialTabPositionValue = tabPositionAnimation.__getValue();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type {StackNavigationOptions} from '@react-navigation/stack';
import React from 'react';
import createCustomBottomTabNavigator from '@libs/Navigation/AppNavigator/createCustomBottomTabNavigator';
import getTopmostCentralPaneRoute from '@libs/Navigation/getTopmostCentralPaneRoute';
import type {BottomTabNavigatorParamList} from '@libs/Navigation/types';
import type {BottomTabNavigatorParamList, CentralPaneName, NavigationPartialRoute, RootStackParamList} from '@libs/Navigation/types';
import SidebarScreen from '@pages/home/sidebar/SidebarScreen';
import SearchPageBottomTab from '@pages/Search/SearchPageBottomTab';
import SCREENS from '@src/SCREENS';
Expand All @@ -19,7 +19,7 @@ const screenOptions: StackNavigationOptions = {
};

function BottomTabNavigator() {
const activeRoute = useNavigationState(getTopmostCentralPaneRoute);
const activeRoute = useNavigationState<RootStackParamList, NavigationPartialRoute<CentralPaneName> | undefined>(getTopmostCentralPaneRoute);

return (
<ActiveRouteContext.Provider value={activeRoute}>
Expand Down
4 changes: 2 additions & 2 deletions src/libs/Navigation/AppNavigator/getPartialStateDiff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ function getPartialStateDiff(state: State<RootStackParamList>, templateState: St
(stateTopmostCentralPane &&
templateStateTopmostCentralPane &&
stateTopmostCentralPane.name !== templateStateTopmostCentralPane.name &&
!shallowCompare(stateTopmostCentralPane.params, templateStateTopmostCentralPane.params))
!shallowCompare(stateTopmostCentralPane.params as Record<string, unknown> | undefined, templateStateTopmostCentralPane.params as Record<string, unknown> | undefined))
) {
// We need to wrap central pane routes in the central pane navigator.
diff[NAVIGATORS.CENTRAL_PANE_NAVIGATOR] = templateStateTopmostCentralPane;
Expand All @@ -73,7 +73,7 @@ function getPartialStateDiff(state: State<RootStackParamList>, templateState: St
(stateTopmostFullScreen &&
templateStateTopmostFullScreen &&
stateTopmostFullScreen.name !== templateStateTopmostFullScreen.name &&
!shallowCompare(stateTopmostFullScreen.params, templateStateTopmostFullScreen.params))
!shallowCompare(stateTopmostFullScreen.params as Record<string, unknown> | undefined, templateStateTopmostFullScreen.params as Record<string, unknown> | undefined))
) {
diff[NAVIGATORS.FULL_SCREEN_NAVIGATOR] = fullScreenDiff;
}
Expand Down
4 changes: 2 additions & 2 deletions src/libs/Navigation/linkTo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,8 @@ export default function linkTo(navigation: NavigationContainerRef<RootStackParam
action.payload.params?.screen === SCREENS.REPORT
? getTopmostReportId(rootState) !== getTopmostReportId(stateFromPath)
: !shallowCompare(
omitBy(topmostCentralPaneRoute?.params, (value) => value === undefined),
omitBy(action.payload.params?.params, (value) => value === undefined),
omitBy(topmostCentralPaneRoute?.params as Record<string, unknown> | undefined, (value) => value === undefined),
omitBy(action.payload.params?.params as Record<string, unknown> | undefined, (value) => value === undefined),
);
// In case if type is 'FORCED_UP' we replace current screen with the provided. This means the current screen no longer exists in the stack
if (type === CONST.NAVIGATION.TYPE.FORCED_UP) {
Expand Down
8 changes: 4 additions & 4 deletions src/libs/ObjectUtils.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// eslint-disable-next-line @typescript-eslint/ban-types
const shallowCompare = (obj1?: object, obj2?: object) => {
const shallowCompare = (obj1?: Record<string, unknown>, obj2?: Record<string, unknown>): boolean => {
if (!obj1 && !obj2) {
return true;
}
if (obj1 && obj2) {
// @ts-expect-error we know that obj1 and obj2 are params of a route.
return Object.keys(obj1).length === Object.keys(obj2).length && Object.keys(obj1).every((key) => obj1[key] === obj2[key]);
const keys1 = Object.keys(obj1);
const keys2 = Object.keys(obj2);
return keys1.length === keys2.length && keys1.every((key) => obj1[key] === obj2[key]);
}
return false;
};
Expand Down
3 changes: 2 additions & 1 deletion src/libs/ReportActionComposeFocusManager.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import React from 'react';
import type {MutableRefObject} from 'react';
import type {TextInput} from 'react-native';
import ROUTES from '@src/ROUTES';
import Navigation from './Navigation/Navigation';

type FocusCallback = (shouldFocusForNonBlurInputOnTapOutside?: boolean) => void;

const composerRef = React.createRef<TextInput>();
const composerRef: MutableRefObject<TextInput | null> = React.createRef<TextInput>();
const editComposerRef = React.createRef<TextInput>();
// There are two types of composer: general composer (edit composer) and main composer.
// The general composer callback will take priority if it exists.
Expand Down
5 changes: 3 additions & 2 deletions src/libs/Url.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'react-native-url-polyfill/auto';
import type {Route} from '@src/ROUTES';

/**
* Add / to the end of any URL if not present
Expand Down Expand Up @@ -48,12 +49,12 @@ function appendParam(url: string, paramName: string, paramValue: string) {
// If parameter exists, replace it
if (url.includes(`${paramName}=`)) {
const regex = new RegExp(`${paramName}=([^&]*)`);
return url.replace(regex, `${paramName}=${paramValue}`);
return url.replace(regex, `${paramName}=${paramValue}`) as Route;
}

// If parameter doesn't exist, append it
const separator = url.includes('?') ? '&' : '?';
return `${url}${separator}${paramName}=${paramValue}`;
return `${url}${separator}${paramName}=${paramValue}` as Route;
}

function hasURL(text: string) {
Expand Down
20 changes: 8 additions & 12 deletions src/libs/migrations/NVPMigration.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import after from 'lodash/after';
import Onyx from 'react-native-onyx';
import type {KeyValueMapping, OnyxEntry} from 'react-native-onyx';
import type {Account} from 'src/types/onyx';
import ONYXKEYS from '@src/ONYXKEYS';
import type {OnyxKey} from '@src/ONYXKEYS';

// These are the oldKeyName: newKeyName of the NVPs we can migrate without any processing
const migrations = {
Expand All @@ -27,35 +30,30 @@ export default function () {

for (const [oldKey, newKey] of Object.entries(migrations)) {
const connectionID = Onyx.connect({
// @ts-expect-error oldKey is a variable
key: oldKey,
key: oldKey as OnyxKey,
callback: (value) => {
Onyx.disconnect(connectionID);
if (value === null) {
resolveWhenDone();
return;
}
// @ts-expect-error These keys are variables, so we can't check the type
Onyx.multiSet({
[newKey]: value,
[oldKey]: null,
}).then(resolveWhenDone);
} as KeyValueMapping).then(resolveWhenDone);
},
});
}
const connectionIDAccount = Onyx.connect({
key: ONYXKEYS.ACCOUNT,
callback: (value) => {
callback: (value: OnyxEntry<Account & {activePolicyID?: string}>) => {
Onyx.disconnect(connectionIDAccount);
// @ts-expect-error we are removing this property, so it is not in the type anymore
if (!value?.activePolicyID) {
resolveWhenDone();
return;
}
// @ts-expect-error we are removing this property, so it is not in the type anymore
const activePolicyID = value.activePolicyID;
const newValue = {...value};
// @ts-expect-error we are removing this property, so it is not in the type anymore
delete newValue.activePolicyID;
Onyx.multiSet({
[ONYXKEYS.NVP_ACTIVE_POLICY_ID]: activePolicyID,
Expand All @@ -72,14 +70,12 @@ export default function () {
resolveWhenDone();
return;
}
const newValue = {};
const newValue = {} as Record<string, unknown>;
for (const key of Object.keys(value)) {
// @ts-expect-error We have no fixed types here
newValue[`nvp_${key}`] = value[key];
// @ts-expect-error We have no fixed types here
newValue[key] = null;
}
Onyx.multiSet(newValue).then(resolveWhenDone);
Onyx.multiSet(newValue as KeyValueMapping).then(resolveWhenDone);
},
});
});
Expand Down
3 changes: 1 addition & 2 deletions src/pages/EnablePayments/AdditionalDetailsStep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,7 @@ function AdditionalDetailsStep({walletAdditionalDetails = DEFAULT_WALLET_ADDITIO
placeholder={translate('common.phoneNumberPlaceholder')}
shouldSaveDraft
/>
{/* @ts-expect-error TODO: Remove this once DatePicker (https://github.com/Expensify/App/issues/25148) is migrated to TypeScript. */}
<InputWrapper<unknown>
<InputWrapper
InputComponent={DatePicker}
inputID="dob"
containerStyles={[styles.mt4]}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ function DateOfBirthUBO({reimbursementAccountDraft, onNext, isEditing, beneficia
submitButtonStyles={[styles.pb5, styles.mb0]}
>
<Text style={[styles.textHeadlineLineHeightXXL]}>{translate('beneficialOwnerInfoStep.enterTheDateOfBirthOfTheOwner')}</Text>
{/* @ts-expect-error TODO: Remove this once DatePicker (https://github.com/Expensify/App/issues/25148) is migrated to TypeScript. */}
<InputWrapper<unknown>
<InputWrapper
InputComponent={DatePicker}
inputID={dobInputID}
label={translate('common.dob')}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,7 @@ function IncorporationDateBusiness({reimbursementAccount, reimbursementAccountDr
submitButtonStyles={[styles.pb5, styles.mb0]}
>
<Text style={[styles.textHeadlineLineHeightXXL]}>{translate('businessInfoStep.selectYourCompanysIncorporationDate')}</Text>
{/* @ts-expect-error TODO: Remove this once DatePicker (https://github.com/Expensify/App/issues/25148) is migrated to TypeScript. */}
<InputWrapper<unknown>
<InputWrapper
InputComponent={DatePicker}
inputID={COMPANY_INCORPORATION_DATE_KEY}
label={translate('businessInfoStep.incorporationDate')}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,7 @@ function DateOfBirth({reimbursementAccount, reimbursementAccountDraft, onNext, i
submitButtonStyles={[styles.pb5, styles.mb0]}
>
<Text style={[styles.textHeadlineLineHeightXXL, styles.mb5]}>{translate('personalInfoStep.enterYourDateOfBirth')}</Text>
{/* @ts-expect-error TODO: Remove this once DatePicker (https://github.com/Expensify/App/issues/25148) is migrated to TypeScript. */}
<InputWrapper<unknown>
<InputWrapper
InputComponent={DatePicker}
inputID={PERSONAL_INFO_DOB_KEY}
label={translate('common.dob')}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,6 @@ function ComposerWithSuggestions(
*/
const setTextInputRef = useCallback(
(el: TextInput) => {
// @ts-expect-error need to reassign this ref
ReportActionComposeFocusManager.composerRef.current = el;
textInputRef.current = el;
if (typeof animatedRef === 'function') {
Expand Down Expand Up @@ -649,7 +648,6 @@ function ComposerWithSuggestions(
const unsubscribeNavigationFocus = navigation.addListener('focus', () => {
KeyDownListener.addKeyDownPressListener(focusComposerOnKeyPress);
// The report isn't unmounted and can be focused again after going back from another report so we should update the composerRef again
// @ts-expect-error need to reassign this ref
ReportActionComposeFocusManager.composerRef.current = textInputRef.current;
setUpComposeFocusManager();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ import SendButton from './SendButton';
type ComposerRef = {
blur: () => void;
focus: (shouldDelay?: boolean) => void;
replaceSelectionWithText: (text: string, shouldAddTrailSpace: boolean) => void;
replaceSelectionWithText: EmojiPickerActions.OnEmojiSelected;
prepareCommentAndResetComposer: () => string;
isFocused: () => boolean;
};
Expand All @@ -73,9 +73,9 @@ type ReportActionComposeOnyxProps = {

type ReportActionComposeProps = ReportActionComposeOnyxProps &
WithCurrentUserPersonalDetailsProps &
Pick<ComposerWithSuggestionsProps, 'reportID' | 'isEmptyChat' | 'isComposerFullSize' | 'disabled' | 'listHeight' | 'lastReportAction'> & {
Pick<ComposerWithSuggestionsProps, 'reportID' | 'isEmptyChat' | 'isComposerFullSize' | 'listHeight' | 'lastReportAction'> & {
/** A method to call when the form is submitted */
onSubmit: (newComment: string | undefined) => void;
onSubmit: (newComment: string) => void;

/** The report currently being looked at */
report: OnyxEntry<OnyxTypes.Report>;
Expand All @@ -91,6 +91,9 @@ type ReportActionComposeProps = ReportActionComposeOnyxProps &

/** A method to call when the input is blur */
onComposerBlur?: () => void;

/** Should the input be disabled */
disabled?: boolean;
};

// We want consistent auto focus behavior on input between native and mWeb so we have some auto focus management code that will
Expand All @@ -102,7 +105,7 @@ const willBlurTextInputOnTapOutside = willBlurTextInputOnTapOutsideFunc();
function ReportActionCompose({
blockedFromConcierge,
currentUserPersonalDetails = {},
disabled,
disabled = false,
isComposerFullSize = false,
onSubmit,
pendingAction,
Expand Down Expand Up @@ -482,7 +485,6 @@ function ReportActionCompose({
<EmojiPickerButton
isDisabled={isBlockedFromConcierge || disabled}
onModalHide={focus}
// @ts-expect-error TODO: Remove this once EmojiPickerButton (https://github.com/Expensify/App/issues/25155) is migrated to TypeScript.
onEmojiSelected={(...args) => composerRef.current?.replaceSelectionWithText(...args)}
emojiPickerID={report?.reportID}
shiftVertical={emojiShiftVertical}
Expand Down
2 changes: 1 addition & 1 deletion src/pages/home/report/ReportActionItemMessageEdit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -419,8 +419,8 @@ function ReportActionItemMessageEdit(
}}
onBlur={(event: NativeSyntheticEvent<TextInputFocusEventData>) => {
setIsFocused(false);
// @ts-expect-error TODO: TextInputFocusEventData doesn't contain relatedTarget.
const relatedTargetId = event.nativeEvent?.relatedTarget?.id;
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
if ((relatedTargetId && [messageEditInput, emojiButtonID].includes(relatedTargetId)) || EmojiPickerAction.isEmojiPickerVisible()) {
return;
}
Expand Down
1 change: 0 additions & 1 deletion src/pages/home/report/ReportFooter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,6 @@ function ReportFooter({
<View style={[chatFooterStyles, isComposerFullSize && styles.chatFooterFullCompose]}>
<SwipeableView onSwipeDown={Keyboard.dismiss}>
<ReportActionCompose
// @ts-expect-error TODO: Remove this once ReportActionCompose (https://github.com/Expensify/App/issues/31984) is migrated to TypeScript.
onSubmit={onSubmitComment}
onComposerFocus={onComposerFocus}
onComposerBlur={onComposerBlur}
Expand Down
Loading

0 comments on commit 4499fa2

Please sign in to comment.