Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[No QA] Enable no-unsafe-argument eslint rule #42391

Merged
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ module.exports = {
__DEV__: 'readonly',
},
rules: {
'@typescript-eslint/no-unsafe-argument': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
Expand Down
11 changes: 8 additions & 3 deletions .github/actions/javascript/bumpVersion/bumpVersion.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as core from '@actions/core';
import {exec as originalExec} from 'child_process';
import fs from 'fs';
import type {PackageJson} from 'type-fest';
import {promisify} from 'util';
import {generateAndroidVersionCode, updateAndroidVersion, updateiOSVersion} from '@github/libs/nativeVersionUpdater';
import * as versionUpdater from '@github/libs/versionUpdater';
Expand All @@ -19,7 +20,7 @@ function updateNativeVersions(version: string) {
.then(() => {
console.log('Successfully updated Android!');
})
.catch((err) => {
.catch((err: string | Error) => {
console.error('Error updating Android');
core.setFailed(err);
});
Expand Down Expand Up @@ -47,8 +48,12 @@ if (!semanticVersionLevel || !Object.keys(versionUpdater.SEMANTIC_VERSION_LEVELS
console.log(`Invalid input for 'SEMVER_LEVEL': ${semanticVersionLevel}`, `Defaulting to: ${semanticVersionLevel}`);
}

const {version: previousVersion} = JSON.parse(fs.readFileSync('./package.json').toString());
const newVersion = versionUpdater.incrementVersion(previousVersion, semanticVersionLevel);
const {version: previousVersion}: PackageJson = JSON.parse(fs.readFileSync('./package.json').toString());
if (!previousVersion) {
core.setFailed('Error: Could not read package.json');
}

const newVersion = versionUpdater.incrementVersion(previousVersion ?? '', semanticVersionLevel);
console.log(`Previous version: ${previousVersion}`, `New version: ${newVersion}`);

updateNativeVersions(newVersion);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ const run = function (): Promise<void> {
core.setOutput('HAS_DEPLOY_BLOCKERS', false);
}
})
.catch((error) => {
.catch((error: string | Error) => {
console.error('A problem occurred while trying to communicate with the GitHub API', error);
core.setFailed(error);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const run = () => {

// Extract timestamp, Graphite accepts timestamp in seconds
if (current.metadata?.creationDate) {
timestamp = Math.floor(new Date(current.metadata.creationDate).getTime() / 1000);
timestamp = Math.floor(new Date(current.metadata.creationDate as string).getTime() / 1000);
}

if (current.name && current.meanDuration && current.meanCount && timestamp) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import * as core from '@actions/core';
import {readFileSync} from 'fs';
import type {PackageJson} from 'type-fest';
import * as versionUpdater from '@github/libs/versionUpdater';

const semverLevel = core.getInput('SEMVER_LEVEL', {required: true});
if (!semverLevel || !Object.values<string>(versionUpdater.SEMANTIC_VERSION_LEVELS).includes(semverLevel)) {
core.setFailed(`'Error: Invalid input for 'SEMVER_LEVEL': ${semverLevel}`);
}

const {version: currentVersion} = JSON.parse(readFileSync('./package.json', 'utf8'));
const previousVersion = versionUpdater.getPreviousVersion(currentVersion, semverLevel);
const {version: currentVersion}: PackageJson = JSON.parse(readFileSync('./package.json', 'utf8'));
if (!currentVersion) {
core.setFailed('Error: Could not read package.json');
}

const previousVersion = versionUpdater.getPreviousVersion(currentVersion ?? '', semverLevel);
core.setOutput('PREVIOUS_VERSION', previousVersion);
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ function checkIssueForCompletedChecklist(numberOfChecklistItems: number) {

getNumberOfItemsFromReviewerChecklist()
.then(checkIssueForCompletedChecklist)
.catch((err) => {
.catch((err: string | Error) => {
console.error(err);
core.setFailed(err);
});
2 changes: 1 addition & 1 deletion .github/scripts/detectRedirectCycle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ function detectCycle(): boolean {

fs.createReadStream(`${process.cwd()}/docs/redirects.csv`)
.pipe(parser)
.on('data', (row) => {
.on('data', (row: [string, string]) => {
// Create a directed graph of sourceURL -> targetURL
addEdge(row[0], row[1]);
})
Expand Down
2 changes: 1 addition & 1 deletion desktop/contextBridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ contextBridge.exposeInMainWorld('electron', {
}

// Deliberately strip event as it includes `sender`
ipcRenderer.on(channel, (event, ...args) => func(...args));
ipcRenderer.on(channel, (event, ...args: unknown[]) => func(...args));
},

/** Remove listeners for a single channel from the main process and sent to the renderer process. */
Expand Down
4 changes: 2 additions & 2 deletions desktop/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ const mainWindow = (): Promise<void> => {
app.hide();
}

ipcMain.on(ELECTRON_EVENTS.LOCALE_UPDATED, (event, updatedLocale) => {
ipcMain.on(ELECTRON_EVENTS.LOCALE_UPDATED, (event, updatedLocale: Locale) => {
Menu.setApplicationMenu(Menu.buildFromTemplate(localizeMenuItems(initialMenuTemplate, updatedLocale)));
disposeContextMenu();
disposeContextMenu = createContextMenu(updatedLocale);
Expand All @@ -601,7 +601,7 @@ const mainWindow = (): Promise<void> => {

// Listen to badge updater event emitted by the render process
// and update the app badge count (MacOS only)
ipcMain.on(ELECTRON_EVENTS.REQUEST_UPDATE_BADGE_COUNT, (event, totalCount) => {
ipcMain.on(ELECTRON_EVENTS.REQUEST_UPDATE_BADGE_COUNT, (event, totalCount?: number) => {
if (totalCount === -1) {
// The electron docs say you should be able to update this and pass no parameters to set the badge
// to a single red dot, but in practice it resulted in an error "TypeError: Insufficient number of
Expand Down
4 changes: 2 additions & 2 deletions src/components/AttachmentPicker/index.native.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ function AttachmentPicker({type = CONST.ATTACHMENT_PICKER_TYPE.FILE, children, s
*/
const showDocumentPicker = useCallback(
(): Promise<DocumentPickerResponse[] | void> =>
RNDocumentPicker.pick(getDocumentPickerOptions(type)).catch((error) => {
RNDocumentPicker.pick(getDocumentPickerOptions(type)).catch((error: TypeError) => {
if (RNDocumentPicker.isCancel(error)) {
return;
}
Expand Down Expand Up @@ -247,7 +247,7 @@ function AttachmentPicker({type = CONST.ATTACHMENT_PICKER_TYPE.FILE, children, s
.then((result) => {
completeAttachmentSelection.current(result);
})
.catch((error) => {
.catch((error: Error) => {
showGeneralAlert(error.message);
throw error;
});
Expand Down
5 changes: 3 additions & 2 deletions src/components/Attachments/AttachmentCarousel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,14 @@ function AttachmentCarousel({report, reportActions, parentReportActions, source,
return;
}

const item: Attachment = entry.item;
if (entry.index !== null) {
setPage(entry.index);
setActiveSource(entry.item.source);
setActiveSource(item.source);
}

if (onNavigate) {
onNavigate(entry.item);
onNavigate(item);
}
},
[isFullScreenRef, onNavigate],
Expand Down
2 changes: 1 addition & 1 deletion src/components/Composer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ function Composer(
if (shouldCalculateCaretPosition && isRendered) {
// we do flushSync to make sure that the valueBeforeCaret is updated before we calculate the caret position to receive a proper position otherwise we will calculate position for the previous state
flushSync(() => {
setValueBeforeCaret(webEvent.target.value.slice(0, webEvent.nativeEvent.selection.start));
setValueBeforeCaret((webEvent.target as HTMLInputElement).value.slice(0, webEvent.nativeEvent.selection.start));
setCaretContent(getNextChars(value ?? '', webEvent.nativeEvent.selection.start));
});
const selectionValue = {
Expand Down
5 changes: 4 additions & 1 deletion src/components/Icon/__mocks__/Expensicons.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
const Expensicons = jest.requireActual('../Expensicons');
// eslint-disable-next-line import/no-import-module-exports
import type {SvgProps} from 'react-native-svg';

const Expensicons = jest.requireActual<Record<string, React.FC<SvgProps>>>('../Expensicons');

module.exports = Object.keys(Expensicons).reduce((prev, curr) => {
// We set the name of the anonymous mock function here so we can dynamically build the list of mocks and access the
Expand Down
2 changes: 1 addition & 1 deletion src/components/OfflineWithFeedback.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ function OfflineWithFeedback({
};

if (child.props.children) {
props.children = applyStrikeThrough(child.props.children);
props.children = applyStrikeThrough(child.props.children as React.ReactNode);
}

return React.cloneElement(child, props);
Expand Down
5 changes: 3 additions & 2 deletions src/components/Onfido/BaseOnfidoWeb.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {Onfido as OnfidoSDK} from 'onfido-sdk-ui';
import type {ErrorType} from 'onfido-sdk-ui/types/Types';
import React, {forwardRef, useEffect} from 'react';
import type {ForwardedRef} from 'react';
import type {LocaleContextProps} from '@components/LocaleContextProvider';
Expand Down Expand Up @@ -92,9 +93,9 @@ function initializeOnfido({sdkToken, onSuccess, onError, onUserExit, preferredLo
}
onSuccess(data);
},
onError: (error) => {
onError: (error: ErrorType) => {
const errorType = error.type;
const errorMessage = error.message ?? CONST.ERROR.UNKNOWN_ERROR;
const errorMessage: string = error.message ?? CONST.ERROR.UNKNOWN_ERROR;
Log.hmmm('Onfido error', {errorType, errorMessage});
if (errorType === CONST.WALLET.ERROR.ONFIDO_USER_CONSENT_DENIED) {
onUserExit();
Expand Down
7 changes: 4 additions & 3 deletions src/components/Onfido/index.native.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {OnfidoCaptureType, OnfidoCountryCode, OnfidoDocumentType, Onfido as OnfidoSDK, OnfidoTheme} from '@onfido/react-native-sdk';
import type {ErrorType} from 'onfido-sdk-ui/types/Types';
import React, {useEffect} from 'react';
import {Alert, Linking} from 'react-native';
import {checkMultiple, PERMISSIONS, RESULTS} from 'react-native-permissions';
Expand Down Expand Up @@ -29,15 +30,15 @@ function Onfido({sdkToken, onUserExit, onSuccess, onError}: OnfidoProps) {
},
})
.then(onSuccess)
.catch((error) => {
const errorMessage = error.message ?? CONST.ERROR.UNKNOWN_ERROR;
.catch((error: ErrorType) => {
const errorMessage: string = error.message ?? CONST.ERROR.UNKNOWN_ERROR;
const errorType = error.type;

Log.hmmm('Onfido error on native', {errorType, errorMessage});

// If the user cancels the Onfido flow we won't log this error as it's normal. In the React Native SDK the user exiting the flow will trigger this error which we can use as
// our "user exited the flow" callback. On web, this event has it's own callback passed as a config so we don't need to bother with this there.
if ([CONST.ONFIDO.ERROR.USER_CANCELLED, CONST.ONFIDO.ERROR.USER_TAPPED_BACK, CONST.ONFIDO.ERROR.USER_EXITED].includes(errorMessage)) {
if (([CONST.ONFIDO.ERROR.USER_CANCELLED, CONST.ONFIDO.ERROR.USER_TAPPED_BACK, CONST.ONFIDO.ERROR.USER_EXITED] as string[]).includes(errorMessage)) {
onUserExit();
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ function BaseProfilingToolMenu({isProfilingInProgress = false, pathToBeUsed, dis
.then(() => {
Log.hmmm('[ProfilingToolMenu] file copied successfully');
})
.catch((error) => {
.catch((error: Record<string, unknown>) => {
Log.hmmm('[ProfilingToolMenu] error copying file: ', error);
});

Expand Down
6 changes: 3 additions & 3 deletions src/components/SignInButtons/AppleSignIn/index.android.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ function AppleSignIn() {
const handleSignIn = () => {
appleSignInRequest()
.then((token) => Session.beginAppleSignIn(token))
.catch((e) => {
if (e.message === appleAuthAndroid.Error.SIGNIN_CANCELLED) {
.catch((error: Record<string, unknown>) => {
if (error.message === appleAuthAndroid.Error.SIGNIN_CANCELLED) {
return null;
}
Log.alert('[Apple Sign In] Apple authentication failed', e);
Log.alert('[Apple Sign In] Apple authentication failed', error);
});
};
return (
Expand Down
7 changes: 4 additions & 3 deletions src/components/SignInButtons/AppleSignIn/index.ios.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import appleAuth from '@invertase/react-native-apple-authentication';
import type {AppleError} from '@invertase/react-native-apple-authentication';
import React from 'react';
import IconButton from '@components/SignInButtons/IconButton';
import Log from '@libs/Log';
Expand Down Expand Up @@ -35,11 +36,11 @@ function AppleSignIn() {
const handleSignIn = () => {
appleSignInRequest()
.then((token) => Session.beginAppleSignIn(token))
.catch((e) => {
if (e.code === appleAuth.Error.CANCELED) {
.catch((error: {code: AppleError}) => {
if (error.code === appleAuth.Error.CANCELED) {
return null;
}
Log.alert('[Apple Sign In] Apple authentication failed', e);
Log.alert('[Apple Sign In] Apple authentication failed', error);
});
};
return (
Expand Down
10 changes: 6 additions & 4 deletions src/libs/EmojiUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import ONYXKEYS from '@src/ONYXKEYS';
import type {FrequentlyUsedEmoji, Locale} from '@src/types/onyx';
import type {ReportActionReaction, UsersReactions} from '@src/types/onyx/ReportActionReactions';
import type IconAsset from '@src/types/utils/IconAsset';
import type EmojiTrie from './EmojiTrie';
import type {SupportedLanguage} from './EmojiTrie';

type HeaderIndice = {code: string; index: number; icon: IconAsset};
type EmojiSpacer = {code: string; spacer: boolean};
Expand Down Expand Up @@ -312,9 +314,9 @@ function getAddedEmojis(currentEmojis: Emoji[], formerEmojis: Emoji[]): Emoji[]
*/
function replaceEmojis(text: string, preferredSkinTone: OnyxEntry<number | string> = CONST.EMOJI_DEFAULT_SKIN_TONE, lang: Locale = CONST.LOCALES.DEFAULT): ReplacedEmoji {
// emojisTrie is importing the emoji JSON file on the app starting and we want to avoid it
const emojisTrie = require('./EmojiTrie').default;
const emojisTrie: typeof EmojiTrie = require('./EmojiTrie').default;

const trie = emojisTrie[lang];
const trie = emojisTrie[lang as SupportedLanguage];
if (!trie) {
return {text, emojis: []};
}
Expand Down Expand Up @@ -390,9 +392,9 @@ function replaceAndExtractEmojis(text: string, preferredSkinTone: OnyxEntry<numb
*/
function suggestEmojis(text: string, lang: Locale, limit: number = CONST.AUTO_COMPLETE_SUGGESTER.MAX_AMOUNT_OF_SUGGESTIONS): Emoji[] | undefined {
// emojisTrie is importing the emoji JSON file on the app starting and we want to avoid it
const emojisTrie = require('./EmojiTrie').default;
const emojisTrie: typeof EmojiTrie = require('./EmojiTrie').default;

const trie = emojisTrie[lang];
const trie = emojisTrie[lang as SupportedLanguage];
if (!trie) {
return [];
}
Expand Down
2 changes: 1 addition & 1 deletion src/libs/Environment/betaChecker/index.android.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ function isBetaBuild(): IsBetaBuild {
fetch(CONST.GITHUB_RELEASE_URL)
.then((res) => res.json())
.then((json) => {
const productionVersion = json.tag_name;
const productionVersion: string | semver.SemVer = json.tag_name;
if (!productionVersion) {
AppUpdate.setIsAppInBeta(false);
resolve(false);
Expand Down
2 changes: 1 addition & 1 deletion src/libs/Localize/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ type Phrase<TKey extends TranslationPaths> = TranslationFlatObject[TKey] extends
*/
const translationCache = new Map<ValueOf<typeof CONST.LOCALES>, Map<TranslationPaths, string>>(
Object.values(CONST.LOCALES).reduce((cache, locale) => {
cache.push([locale, new Map()]);
cache.push([locale, new Map<TranslationPaths, string>()]);
return cache;
}, [] as Array<[ValueOf<typeof CONST.LOCALES>, Map<TranslationPaths, string>]>),
);
Expand Down
21 changes: 12 additions & 9 deletions src/libs/Middleware/Logging.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {SIDE_EFFECT_REQUEST_COMMANDS} from '@libs/API/types';
import type HttpsError from '@libs/Errors/HttpsError';
import Log from '@libs/Log';
import CONST from '@src/CONST';
import type Request from '@src/types/onyx/Request';
Expand Down Expand Up @@ -42,7 +43,7 @@ const Logging: Middleware = (response, request) => {
logRequestDetails(`Finished API request in ${Date.now() - startTime}ms`, request, data);
return data;
})
.catch((error) => {
.catch((error: HttpsError) => {
const logParams: Record<string, unknown> = {
message: error.message,
status: error.status,
Expand All @@ -64,18 +65,20 @@ const Logging: Middleware = (response, request) => {
// incorrect url, bad cors headers returned by the server, DNS lookup failure etc.
Log.hmmm('[Network] API request error: Failed to fetch', logParams);
} else if (
[
CONST.ERROR.IOS_NETWORK_CONNECTION_LOST,
CONST.ERROR.NETWORK_REQUEST_FAILED,
CONST.ERROR.IOS_NETWORK_CONNECTION_LOST_RUSSIAN,
CONST.ERROR.IOS_NETWORK_CONNECTION_LOST_SWEDISH,
CONST.ERROR.IOS_NETWORK_CONNECTION_LOST_SPANISH,
].includes(error.message)
(
[
CONST.ERROR.IOS_NETWORK_CONNECTION_LOST,
CONST.ERROR.NETWORK_REQUEST_FAILED,
CONST.ERROR.IOS_NETWORK_CONNECTION_LOST_RUSSIAN,
CONST.ERROR.IOS_NETWORK_CONNECTION_LOST_SWEDISH,
CONST.ERROR.IOS_NETWORK_CONNECTION_LOST_SPANISH,
] as string[]
).includes(error.message)
) {
// These errors seem to happen for native devices with interrupted connections. Often we will see logs about Pusher disconnecting together with these.
// This type of error may also indicate a problem with SSL certs.
Log.hmmm('[Network] API request error: Connection interruption likely', logParams);
} else if ([CONST.ERROR.FIREFOX_DOCUMENT_LOAD_ABORTED, CONST.ERROR.SAFARI_DOCUMENT_LOAD_ABORTED].includes(error.message)) {
} else if (([CONST.ERROR.FIREFOX_DOCUMENT_LOAD_ABORTED, CONST.ERROR.SAFARI_DOCUMENT_LOAD_ABORTED] as string[]).includes(error.message)) {
// This message can be observed page load is interrupted (closed or navigated away).
Log.hmmm('[Network] API request error: User likely navigated away from or closed browser', logParams);
} else if (error.message === CONST.ERROR.IOS_LOAD_FAILED) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ export default {
*/
clearNotifications(shouldClearNotification: (notificationData: LocalNotificationData) => boolean) {
Object.values(notificationCache)
.filter((notification) => shouldClearNotification(notification.data))
.filter((notification) => shouldClearNotification(notification.data as LocalNotificationData))
.forEach((notification) => notification.close());
},
};
2 changes: 1 addition & 1 deletion src/libs/Notification/PushNotification/index.native.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ const register: Register = (notificationID) => {
// Refresh notification opt-in status NVP for the new user.
refreshNotificationOptInStatus();
})
.catch((error) => {
.catch((error: Record<string, unknown>) => {
Log.warn('[PushNotification] Failed to register for push notifications! Reason: ', error);
});
};
Expand Down
Loading
Loading