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

Enable no-unsafe-member-access eslint rule #43557

Merged
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
b825ac9
enable no-member-access rule
bgawkuc Jun 6, 2024
2286f81
add draft solution for require errors
bgawkuc Jun 6, 2024
b60e0ba
override node require interface
bgawkuc Jun 6, 2024
372319f
fix no member access error in navigation files
bgawkuc Jun 6, 2024
f4730ca
fix no member access error in require usages
bgawkuc Jun 6, 2024
4f82ac1
use generic type with require
bgawkuc Jun 6, 2024
7a68f02
fix crashing desktop
bgawkuc Jun 6, 2024
37a8032
fix no member access error for error type
bgawkuc Jun 7, 2024
933a865
fix more no member access errors
bgawkuc Jun 7, 2024
3a80440
fix no unsafe member access errors in tests
bgawkuc Jun 10, 2024
73df95f
fix no unsafe member access errors in tests 2
bgawkuc Jun 11, 2024
74c8147
simplify types
bgawkuc Jun 12, 2024
d5fd866
Merge branch 'main' into ts/enable-no-unsafe-member-access
bgawkuc Jun 12, 2024
a4e6bc6
review adjustments
bgawkuc Jun 12, 2024
d4fbe38
fix kie/act-js types
bgawkuc Jun 13, 2024
64ca929
Merge branch 'main' into ts/enable-no-unsafe-member-access
bgawkuc Jun 13, 2024
04fcd4b
fix kie/act-js types
bgawkuc Jun 13, 2024
852ef29
wip
bgawkuc Jun 14, 2024
d7b053c
improve custom step identifier type
bgawkuc Jun 14, 2024
0dfd63c
remove redundant module
bgawkuc Jun 14, 2024
ba0b925
Merge branch 'main' into ts/enable-no-unsafe-member-access
bgawkuc Jun 17, 2024
c708fe4
Fix @kie/act-js types
blazejkustra Jun 17, 2024
9859158
move EventJSON export to custom module
bgawkuc Jun 17, 2024
2156f68
review adjustments
bgawkuc Jun 18, 2024
feec659
Merge branch 'main' into ts/enable-no-unsafe-member-access
bgawkuc Jun 18, 2024
c47a908
review adjustments
bgawkuc Jun 18, 2024
ece8190
Merge branch 'main' into ts/enable-no-unsafe-member-access
bgawkuc Jun 18, 2024
c5b93db
add error type
bgawkuc Jun 18, 2024
f139618
update RN type
bgawkuc Jun 18, 2024
fefc1a2
Merge branch 'main' into ts/enable-no-unsafe-member-access
blazejkustra Jun 19, 2024
9783a00
Merge branch 'main' into ts/enable-no-unsafe-member-access
blazejkustra Jun 20, 2024
1212d13
Merge branch 'main' into ts/enable-no-unsafe-member-access
blazejkustra Jun 24, 2024
e5907c2
Fix new lint errors
blazejkustra Jun 24, 2024
81a96d8
Merge branch 'main' into ts/enable-no-unsafe-member-access
blazejkustra Jun 24, 2024
683e4c0
Fix lint error
blazejkustra Jun 24, 2024
05f12a4
Merge branch 'main' into ts/enable-no-unsafe-member-access
blazejkustra Jun 25, 2024
15a5db2
Add generic argument to require
blazejkustra Jun 25, 2024
0bb01b7
Remove unnecessary assertion
blazejkustra Jun 25, 2024
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 @@ -105,7 +105,6 @@ module.exports = {
__DEV__: 'readonly',
},
rules: {
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',

// TypeScript specific rules
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as github from '@actions/github';
import type {WebhookPayload} from '@actions/github/lib/interfaces';
import {parse} from '@babel/parser';
import traverse from '@babel/traverse';
import CONST from '@github/libs/CONST';
Expand All @@ -8,6 +9,15 @@ import type Category from './Category';

type SuperClassType = {superClass: {name?: string; object: {name: string}; property: {name: string}} | null; name: string};

type GithubPaylod = WebhookPayload & {
// eslint-disable-next-line @typescript-eslint/naming-convention
pull_request?: {
head: {
ref?: string;
};
};
};

const items = [
"I verified that similar component doesn't exist in the codebase",
'I verified that all props are defined accurately and each prop has a `/** comment above it */`',
Expand Down Expand Up @@ -77,7 +87,7 @@ async function detectReactComponentInFile(filename: string): Promise<boolean | u
owner: CONST.GITHUB_OWNER,
repo: CONST.APP_REPO,
path: filename,
ref: github.context.payload.pull_request?.head.ref,
ref: (github.context.payload as GithubPaylod)?.pull_request?.head.ref,
};
try {
const {data} = await GithubUtils.octokit.repos.getContent(params);
Expand Down
2 changes: 1 addition & 1 deletion .github/actions/javascript/authorChecklist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16967,7 +16967,7 @@ async function detectReactComponentInFile(filename) {
owner: CONST_1.default.GITHUB_OWNER,
repo: CONST_1.default.APP_REPO,
path: filename,
ref: github.context.payload.pull_request?.head.ref,
ref: github.context.payload?.pull_request?.head.ref,
};
try {
const { data } = await GithubUtils_1.default.octokit.repos.getContent(params);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@ import GitUtils from '@github/libs/GitUtils';

type IssuesCreateResponse = Awaited<ReturnType<typeof GithubUtils.octokit.issues.create>>['data'];

type PackageJSON = {
version: string;
};

async function run(): Promise<IssuesCreateResponse | void> {
// Note: require('package.json').version does not work because ncc will resolve that to a plain string at compile time
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
const newVersionTag: string = packageJson.version;
const packageJson: PackageJSON = JSON.parse(fs.readFileSync('package.json', 'utf8'));
const newVersionTag = packageJson.version;

try {
// Start by fetching the list of recent StagingDeployCash issues, along with the list of open deploy blockers
Expand Down
2 changes: 1 addition & 1 deletion .storybook/webpack.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ switch (process.env.ENV) {
}

const env = dotenv.config({path: path.resolve(__dirname, `../${envFile}`)});
const customFunction: CustomWebpackFunction = require('../config/webpack/webpack.common').default;
const customFunction = require<{default: CustomWebpackFunction}>('../config/webpack/webpack.common').default;
bgawkuc marked this conversation as resolved.
Show resolved Hide resolved

const custom: CustomWebpackConfig = customFunction({file: envFile});

Expand Down
4 changes: 2 additions & 2 deletions __mocks__/react-native-webview.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type {View as RNView} from 'react-native';

jest.mock('react-native-webview', () => {
const {View} = require('react-native');
const {View} = require<{View: RNView}>('react-native');
bgawkuc marked this conversation as resolved.
Show resolved Hide resolved
return {
WebView: () => View as RNView,
WebView: () => View,
};
});
2 changes: 1 addition & 1 deletion desktop/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import type {Locale} from '@src/types/onyx';
import type {CreateDownloadQueue, DownloadItem} from './createDownloadQueue';
import ELECTRON_EVENTS from './ELECTRON_EVENTS';

const createDownloadQueue: CreateDownloadQueue = require('./createDownloadQueue').default;
const createDownloadQueue = require<{default: CreateDownloadQueue}>('./createDownloadQueue').default;
bgawkuc marked this conversation as resolved.
Show resolved Hide resolved

const port = process.env.PORT ?? 8082;
const {DESKTOP_SHORTCUT_ACCELERATOR, LOCALES} = CONST;
Expand Down
2 changes: 1 addition & 1 deletion src/components/AttachmentModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ function AttachmentModal({
}, []);

const isDirectoryCheck = useCallback((data: FileObject) => {
if ('webkitGetAsEntry' in data && typeof data.webkitGetAsEntry === 'function' && data.webkitGetAsEntry().isDirectory) {
if ('webkitGetAsEntry' in data && (data as DataTransferItem).webkitGetAsEntry()?.isDirectory) {
setIsAttachmentInvalid(true);
setAttachmentInvalidReasonTitle('attachmentPicker.attachmentError');
setAttachmentInvalidReason('attachmentPicker.folderNotAllowedMessage');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const launchCamera: LaunchCamera = (options, callback) => {

launchCameraImagePicker(options, callback);
})
.catch((error) => {
.catch((error: ErrorLaunchCamera) => {
/* Intercept the permission error as well as any other errors and call the callback
* follow the same pattern expected for image picker results */
callback({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const launchCamera: LaunchCamera = (options, callback) => {

launchCameraImagePicker(options, callback);
})
.catch((error) => {
.catch((error: ErrorLaunchCamera) => {
/* Intercept the permission error as well as any other errors and call the callback
* follow the same pattern expected for image picker results */
callback({
Expand Down
25 changes: 12 additions & 13 deletions src/components/Hoverable/ActiveHoverable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ import type HoverableProps from './types';

type ActiveHoverableProps = Omit<HoverableProps, 'disabled'>;

type OnMouseEvent = (e: MouseEvent) => void;
type MouseEvents = 'onMouseEnter' | 'onMouseLeave' | 'onMouseMove' | 'onBlur';

type OnMouseEvents = Record<MouseEvents, (e: MouseEvent) => void>;

function ActiveHoverable({onHoverIn, onHoverOut, shouldHandleScroll, shouldFreezeCapture, children}: ActiveHoverableProps, outerRef: Ref<HTMLElement>) {
const [isHovered, setIsHovered] = useState(false);
Expand Down Expand Up @@ -100,26 +102,23 @@ function ActiveHoverable({onHoverIn, onHoverOut, shouldHandleScroll, shouldFreez

const child = useMemo(() => getReturnValue(children, !isScrollingRef.current && isHovered), [children, isHovered]);

const childOnMouseEnter: OnMouseEvent = child.props.onMouseEnter;
const childOnMouseLeave: OnMouseEvent = child.props.onMouseLeave;
const childOnMouseMove: OnMouseEvent = child.props.onMouseMove;
const childOnBlur: OnMouseEvent = child.props.onBlur;
const {onMouseEnter, onMouseLeave, onMouseMove, onBlur}: OnMouseEvents = child.props;

const hoverAndForwardOnMouseEnter = useCallback(
(e: MouseEvent) => {
isVisibiltyHidden.current = false;
updateIsHovered(true);
childOnMouseEnter?.(e);
onMouseEnter?.(e);
},
[updateIsHovered, childOnMouseEnter],
[updateIsHovered, onMouseEnter],
);

const unhoverAndForwardOnMouseLeave = useCallback(
(e: MouseEvent) => {
updateIsHovered(false);
childOnMouseLeave?.(e);
onMouseLeave?.(e);
},
[updateIsHovered, childOnMouseLeave],
[updateIsHovered, onMouseLeave],
);

const unhoverAndForwardOnBlur = useCallback(
Expand All @@ -130,18 +129,18 @@ function ActiveHoverable({onHoverIn, onHoverOut, shouldHandleScroll, shouldFreez
setIsHovered(false);
}

childOnBlur?.(event);
onBlur?.(event);
},
[childOnBlur],
[onBlur],
);

const handleAndForwardOnMouseMove = useCallback(
(e: MouseEvent) => {
isVisibiltyHidden.current = false;
updateIsHovered(true);
childOnMouseMove?.(e);
onMouseMove?.(e);
},
[updateIsHovered, childOnMouseMove],
[updateIsHovered, onMouseMove],
);

return cloneElement(child, {
Expand Down
3 changes: 2 additions & 1 deletion src/components/Modal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import StatusBar from '@libs/StatusBar';
import CONST from '@src/CONST';
import BaseModal from './BaseModal';
import type BaseModalProps from './types';
import type {WindowState} from './types';

function Modal({fullscreen = true, onModalHide = () => {}, type, onModalShow = () => {}, children, shouldHandleNavigationBack, ...rest}: BaseModalProps) {
const theme = useTheme();
Expand All @@ -22,7 +23,7 @@ function Modal({fullscreen = true, onModalHide = () => {}, type, onModalShow = (
const hideModal = () => {
setStatusBarColor(previousStatusBarColor);
onModalHide();
if (window.history.state?.shouldGoBack) {
if ((window.history.state as WindowState)?.shouldGoBack) {
window.history.back();
}
};
Expand Down
6 changes: 5 additions & 1 deletion src/components/Modal/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ type PopoverAnchorPosition = {
left?: number;
};

type WindowState = {
shouldGoBack: boolean;
};

type BaseModalProps = Partial<ModalProps> & {
/** Decides whether the modal should cover fullscreen. FullScreen modal has backdrop */
fullscreen?: boolean;
Expand Down Expand Up @@ -86,4 +90,4 @@ type BaseModalProps = Partial<ModalProps> & {
};

export default BaseModalProps;
export type {PopoverAnchorPosition};
export type {PopoverAnchorPosition, WindowState};
5 changes: 2 additions & 3 deletions src/components/Onfido/BaseOnfidoWeb.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
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 All @@ -12,7 +11,7 @@ import variables from '@styles/variables';
import CONST from '@src/CONST';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
import './index.css';
import type {OnfidoElement, OnfidoProps} from './types';
import type {OnfidoElement, OnfidoError, OnfidoProps} from './types';

type InitializeOnfidoProps = OnfidoProps &
Pick<LocaleContextProps, 'translate' | 'preferredLocale'> & {
Expand Down Expand Up @@ -93,7 +92,7 @@ function initializeOnfido({sdkToken, onSuccess, onError, onUserExit, preferredLo
}
onSuccess(data);
},
onError: (error: ErrorType) => {
onError: (error: OnfidoError) => {
const errorType = error.type;
const errorMessage: string = error.message ?? CONST.ERROR.UNKNOWN_ERROR;
Log.hmmm('Onfido error', {errorType, errorMessage});
Expand Down
5 changes: 2 additions & 3 deletions src/components/Onfido/index.native.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
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 All @@ -9,7 +8,7 @@ import getPlatform from '@libs/getPlatform';
import Log from '@libs/Log';
import CONST from '@src/CONST';
import type {TranslationPaths} from '@src/languages/types';
import type {OnfidoProps} from './types';
import type {OnfidoError, OnfidoProps} from './types';

function Onfido({sdkToken, onUserExit, onSuccess, onError}: OnfidoProps) {
const {translate} = useLocalize();
Expand All @@ -30,7 +29,7 @@ function Onfido({sdkToken, onUserExit, onSuccess, onError}: OnfidoProps) {
},
})
.then(onSuccess)
.catch((error: ErrorType) => {
.catch((error: OnfidoError) => {
const errorMessage: string = error.message ?? CONST.ERROR.UNKNOWN_ERROR;
const errorType = error.type;

Expand Down
6 changes: 5 additions & 1 deletion src/components/Onfido/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,8 @@ type OnfidoProps = {
onError: (error?: string) => void;
};

export type {OnfidoProps, OnfidoElement, OnfidoData, OnfidoDataWithApplicantID};
type OnfidoError = Error & {
type?: string;
};

export type {OnfidoProps, OnfidoElement, OnfidoData, OnfidoDataWithApplicantID, OnfidoError};
8 changes: 5 additions & 3 deletions src/components/SignInButtons/GoogleSignIn/index.native.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import * as Session from '@userActions/Session';
import CONFIG from '@src/CONFIG';
import CONST from '@src/CONST';
import type {GoogleSignInProps} from '.';
import type GoogleError from './types';

/**
* Google Sign In method for iOS and android that returns identityToken.
Expand All @@ -27,17 +28,18 @@ function googleSignInRequest() {
.then((token) => Session.beginGoogleSignIn(token))
.catch((error) => {
bgawkuc marked this conversation as resolved.
Show resolved Hide resolved
// Handle unexpected error shape
if (error === undefined || error.code === undefined) {
const googleError = error as GoogleError;
if (error === undefined || googleError.code === undefined) {
bgawkuc marked this conversation as resolved.
Show resolved Hide resolved
Log.alert(`[Google Sign In] Google sign in failed: ${error}`);
}
bgawkuc marked this conversation as resolved.
Show resolved Hide resolved
/** The logged code is useful for debugging any new errors that are not specifically handled. To decode, see:
- The common status codes documentation: https://developers.google.com/android/reference/com/google/android/gms/common/api/CommonStatusCodes
- The Google Sign In codes documentation: https://developers.google.com/android/reference/com/google/android/gms/auth/api/signin/GoogleSignInStatusCodes
*/
if (error.code === statusCodes.SIGN_IN_CANCELLED) {
if (googleError.code === statusCodes.SIGN_IN_CANCELLED) {
bgawkuc marked this conversation as resolved.
Show resolved Hide resolved
Log.info('[Google Sign In] Google Sign In cancelled');
} else {
Log.alert(`[Google Sign In] Error Code: ${error.code}. ${error.message}`, {}, false);
Log.alert(`[Google Sign In] Error Code: ${googleError.code}. ${googleError.message}`, {}, false);
bgawkuc marked this conversation as resolved.
Show resolved Hide resolved
}
});
}
Expand Down
5 changes: 5 additions & 0 deletions src/components/SignInButtons/GoogleSignIn/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
type GoogleError = Error & {
code?: string;
};

export default GoogleError;
6 changes: 5 additions & 1 deletion src/components/Tooltip/BaseTooltip/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ import variables from '@styles/variables';
import CONST from '@src/CONST';
import callOrReturn from '@src/types/utils/callOrReturn';

type MouseEvents = {
onMouseEnter: (e: MouseEvent) => void | undefined;
};

const hasHoverSupport = DeviceCapabilities.hasHoverSupport();

/**
Expand Down Expand Up @@ -188,7 +192,7 @@ function Tooltip(
(e: MouseEvent) => {
updateTargetAndMousePosition(e);
if (React.isValidElement(children)) {
const onMouseEnter: (e: MouseEvent) => void | undefined = children.props.onMouseEnter;
const onMouseEnter = (children.props as MouseEvents).onMouseEnter;
onMouseEnter?.(e);
}
},
Expand Down
6 changes: 2 additions & 4 deletions src/libs/DomUtils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ const addCSS = (css: string, styleId: string) => {
if (existingStyle) {
if ('styleSheet' in existingStyle) {
// Supports IE8 and below
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(existingStyle.styleSheet as any).cssText = css;
(existingStyle.styleSheet as CSSStyleDeclaration).cssText = css;
} else {
existingStyle.innerHTML = css;
}
Expand All @@ -20,8 +19,7 @@ const addCSS = (css: string, styleId: string) => {

if ('styleSheet' in styleElement) {
// Supports IE8 and below
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(styleElement.styleSheet as any).cssText = css;
(styleElement.styleSheet as CSSStyleDeclaration).cssText = css;
} else {
styleElement.appendChild(document.createTextNode(css));
}
Expand Down
15 changes: 6 additions & 9 deletions src/libs/E2E/reactNativeLaunchingTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,14 @@
* By doing this, we avoid bundling any E2E testing code
* into the actual release app.
*/
import type {ValueOf} from 'type-fest';
import * as Metrics from '@libs/Metrics';
import Performance from '@libs/Performance';
import Config from 'react-native-config';
import E2EConfig from '../../../tests/e2e/config';
import E2EClient from './client';
import installNetworkInterceptor from './utils/NetworkInterceptor';
import LaunchArgs from './utils/LaunchArgs';
import type { TestConfig } from './types';

type Tests = Record<ValueOf<typeof E2EConfig.TEST_NAMES>, (config: TestConfig) => void>;
import type {TestModule, Tests} from './types';

console.debug('==========================');
console.debug('==== Running e2e test ====');
Expand All @@ -34,11 +31,11 @@ if (!appInstanceId) {

// import your test here, define its name and config first in e2e/config.js
const tests: Tests = {
[E2EConfig.TEST_NAMES.AppStartTime]: require('./tests/appStartTimeTest.e2e').default,
[E2EConfig.TEST_NAMES.OpenChatFinderPage]: require('./tests/openChatFinderPageTest.e2e').default,
[E2EConfig.TEST_NAMES.ChatOpening]: require('./tests/chatOpeningTest.e2e').default,
[E2EConfig.TEST_NAMES.ReportTyping]: require('./tests/reportTypingTest.e2e').default,
[E2EConfig.TEST_NAMES.Linking]: require('./tests/linkingTest.e2e').default,
[E2EConfig.TEST_NAMES.AppStartTime]: require<TestModule>('./tests/appStartTimeTest.e2e').default,
[E2EConfig.TEST_NAMES.OpenChatFinderPage]: require<TestModule>('./tests/openChatFinderPageTest.e2e').default,
[E2EConfig.TEST_NAMES.ChatOpening]: require<TestModule>('./tests/chatOpeningTest.e2e').default,
[E2EConfig.TEST_NAMES.ReportTyping]: require<TestModule>('./tests/reportTypingTest.e2e').default,
[E2EConfig.TEST_NAMES.Linking]: require<TestModule>('./tests/linkingTest.e2e').default,
};

// Once we receive the TII measurement we know that the app is initialized and ready to be used:
Expand Down
Loading
Loading