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-assignment eslint rule #44003

Merged
Merged
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
2f676e8
Pass generic parameter to all lottie requires
blazejkustra Jun 19, 2024
c2cbd8e
Remove unsafe assigment
blazejkustra Jun 19, 2024
dd47f88
Add asserts to JSON.parse
blazejkustra Jun 19, 2024
711d028
Use assertion for @vue/preload-webpack-plugin require
blazejkustra Jun 19, 2024
13f8c0f
Fix some of jest scripts and mocks
blazejkustra Jun 19, 2024
a7ab173
Add assertion to Console module
blazejkustra Jun 19, 2024
7fa04b4
Add assertions to yaml parser
blazejkustra Jun 19, 2024
680070a
Change assertion from any to a random actionName
blazejkustra Jun 19, 2024
af0beb8
Add type to Electron download event listener
blazejkustra Jun 19, 2024
1c1b9c4
Remove unnecessary eslint no-unsafe-return comments
blazejkustra Jun 19, 2024
cc84252
Fix jest.requireActual usage
blazejkustra Jun 19, 2024
4b6d7d4
Add assertion to other Json.parse
blazejkustra Jun 19, 2024
582a0b4
Add generic types to requires
blazejkustra Jun 19, 2024
a7fee2d
Mock middleware properly
blazejkustra Jun 19, 2024
14e4588
Assert that prop is a string
blazejkustra Jun 19, 2024
c3cab6b
Add missing args to octokit mocked functions
blazejkustra Jun 19, 2024
88de71a
Add type for backgroundColor
blazejkustra Jun 19, 2024
1f3cd34
Fix minor type issues
blazejkustra Jun 19, 2024
1141173
Augment objectContaining and arrayContaining to return unknown instea…
blazejkustra Jun 19, 2024
31f64f4
Fix minor errors
blazejkustra Jun 19, 2024
3df3669
Add more assertions
blazejkustra Jun 19, 2024
1b6e0a9
Merge branch 'ts/enable-no-unsafe-member-access' into ts/no-unsafe-as…
blazejkustra Jun 20, 2024
267719f
Fix child props
blazejkustra Jun 20, 2024
206cc3d
Rerun lint
blazejkustra Jun 20, 2024
1c2b63b
Merge branch 'ts/enable-no-unsafe-member-access' into ts/no-unsafe-as…
blazejkustra Jun 24, 2024
82c9d74
Fix more eslint errors
blazejkustra Jun 24, 2024
b9d363e
Merge branch 'ts/enable-no-unsafe-member-access' into ts/no-unsafe-as…
blazejkustra Jun 24, 2024
d6f851c
Merge branch 'main' into ts/no-unsafe-assignment
blazejkustra Jun 25, 2024
021e09f
Merge branch 'main' into ts/no-unsafe-assignment
blazejkustra Jun 25, 2024
99cffb5
Address review comments
blazejkustra Jun 25, 2024
bfb7032
Fix one more error in tests
blazejkustra Jun 25, 2024
f9578f9
Fix after internal review
blazejkustra Jun 25, 2024
22fd2c6
Merge branch 'main' into ts/no-unsafe-assignment
blazejkustra Jul 1, 2024
e47f7e1
Disable rules in debug.ts
blazejkustra Jul 1, 2024
b8391ed
Fix prettier
blazejkustra Jul 1, 2024
8ca6a9a
Merge branch 'main' into ts/no-unsafe-assignment
blazejkustra Jul 2, 2024
825b310
Fix eslint errors
blazejkustra Jul 2, 2024
2f656bf
Merge branch 'main' into ts/no-unsafe-assignment
blazejkustra Jul 3, 2024
3d649b3
Add eslint disable to a todo comment
blazejkustra Jul 3, 2024
0032c88
Merge branch 'main' into ts/no-unsafe-assignment
blazejkustra Jul 3, 2024
45b02a7
Fix eslint
blazejkustra Jul 3, 2024
20bb70c
Merge branch 'main' into ts/no-unsafe-assignment
blazejkustra Jul 4, 2024
185901f
Cast to unknown
blazejkustra Jul 4, 2024
f9587a0
Merge branch 'main' into ts/no-unsafe-assignment
blazejkustra Jul 4, 2024
0cc3676
Add eslint disable to a todo comment
blazejkustra Jul 4, 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 @@ -109,7 +109,6 @@ module.exports = {
},
rules: {
// TypeScript specific rules
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/prefer-enum-initializers': 'error',
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-non-null-assertion': 'error',
Expand Down
2 changes: 1 addition & 1 deletion .github/actions/javascript/bumpVersion/bumpVersion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ if (!semanticVersionLevel || !versionUpdater.isValidSemverLevel(semanticVersionL
console.log(`Invalid input for 'SEMVER_LEVEL': ${semanticVersionLevel}`, `Defaulting to: ${semanticVersionLevel}`);
}

const {version: previousVersion}: PackageJson = JSON.parse(fs.readFileSync('./package.json').toString());
const {version: previousVersion} = JSON.parse(fs.readFileSync('./package.json').toString()) as PackageJson;
if (!previousVersion) {
core.setFailed('Error: Could not read package.json');
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ import GitUtils from '@github/libs/GitUtils';

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

type PackageJSON = {
type PackageJson = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why we renamed this, I think PackageJSON works better with out naming conventions

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: PackageJSON = JSON.parse(fs.readFileSync('package.json', 'utf8'));
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8')) as PackageJson;
const newVersionTag = packageJson.version;

try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const run = () => {
}

try {
const current: RegressionEntry = JSON.parse(entry);
const current = JSON.parse(entry) as RegressionEntry;

// Extract timestamp, Graphite accepts timestamp in seconds
if (current.metadata?.creationDate) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ function run() {
core.setFailed(`'Error: Invalid input for 'SEMVER_LEVEL': ${semverLevel}`);
}

const {version: currentVersion}: PackageJson = JSON.parse(readFileSync('./package.json', 'utf8'));
const {version: currentVersion} = JSON.parse(readFileSync('./package.json', 'utf8')) as PackageJson;
if (!currentVersion) {
core.setFailed('Error: Could not read package.json');
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type {CompareResult, PerformanceEntry} from '@callstack/reassure-compare/
import fs from 'fs';

const run = (): boolean => {
const regressionOutput: CompareResult = JSON.parse(fs.readFileSync('.reassure/output.json', 'utf8'));
const regressionOutput = JSON.parse(fs.readFileSync('.reassure/output.json', 'utf8')) as CompareResult;
const countDeviation = Number(core.getInput('COUNT_DEVIATION', {required: true}));
const durationDeviation = Number(core.getInput('DURATION_DEVIATION_PERCENTAGE', {required: true}));

Expand Down
16 changes: 8 additions & 8 deletions __mocks__/@ua/react-native-airship.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,31 +15,31 @@ const iOS: Partial<typeof AirshipIOS> = {
},
};

const pushIOS: AirshipPushIOS = jest.fn().mockImplementation(() => ({
const pushIOS = jest.fn().mockImplementation(() => ({
setBadgeNumber: jest.fn(),
setForegroundPresentationOptions: jest.fn(),
setForegroundPresentationOptionsCallback: jest.fn(),
}))();
}))() as AirshipPushIOS;

const pushAndroid: AirshipPushAndroid = jest.fn().mockImplementation(() => ({
const pushAndroid = jest.fn().mockImplementation(() => ({
setForegroundDisplayPredicate: jest.fn(),
}))();
}))() as AirshipPushAndroid;

const push: AirshipPush = jest.fn().mockImplementation(() => ({
const push = jest.fn().mockImplementation(() => ({
iOS: pushIOS,
android: pushAndroid,
enableUserNotifications: () => Promise.resolve(false),
clearNotifications: jest.fn(),
getNotificationStatus: () => Promise.resolve({airshipOptIn: false, systemEnabled: false, airshipEnabled: false}),
getActiveNotifications: () => Promise.resolve([]),
}))();
}))() as AirshipPush;

const contact: AirshipContact = jest.fn().mockImplementation(() => ({
const contact = jest.fn().mockImplementation(() => ({
identify: jest.fn(),
getNamedUserId: () => Promise.resolve(undefined),
reset: jest.fn(),
module: jest.fn(),
}))();
}))() as AirshipContact;

const Airship: Partial<AirshipRoot> = {
addListener: jest.fn(),
Expand Down
1 change: 1 addition & 0 deletions __mocks__/fs.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
const {fs} = require('memfs');

module.exports = fs;
4 changes: 2 additions & 2 deletions __mocks__/react-native.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jest.doMock('react-native', () => {
};
};

const reactNativeMock: ReactNativeMock = Object.setPrototypeOf(
const reactNativeMock = Object.setPrototypeOf(
{
NativeModules: {
...ReactNative.NativeModules,
Expand Down Expand Up @@ -102,7 +102,7 @@ jest.doMock('react-native', () => {
},
},
ReactNative,
);
) as ReactNativeMock;

return reactNativeMock;
});
13 changes: 5 additions & 8 deletions config/webpack/webpack.common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,24 @@ import dotenv from 'dotenv';
import fs from 'fs';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import path from 'path';
import type {Compiler, Configuration} from 'webpack';
import type {Class} from 'type-fest';
import type {Configuration, WebpackPluginInstance} from 'webpack';
import {DefinePlugin, EnvironmentPlugin, IgnorePlugin, ProvidePlugin} from 'webpack';
import {BundleAnalyzerPlugin} from 'webpack-bundle-analyzer';
import CustomVersionFilePlugin from './CustomVersionFilePlugin';
import type Environment from './types';

// importing anything from @vue/preload-webpack-plugin causes an error
type Options = {
rel: string;
as: string;
fileWhitelist: RegExp[];
include: string;
};

type PreloadWebpackPluginClass = {
new (options?: Options): PreloadWebpackPluginClass;
apply: (compiler: Compiler) => void;
};
type PreloadWebpackPluginClass = Class<WebpackPluginInstance, [Options]>;

// require is necessary, there are no types for this package and the declaration file can't be seen by the build process which causes an error.
const PreloadWebpackPlugin: PreloadWebpackPluginClass = require('@vue/preload-webpack-plugin');
// require is necessary, importing anything from @vue/preload-webpack-plugin causes an error
const PreloadWebpackPlugin = require('@vue/preload-webpack-plugin') as PreloadWebpackPluginClass;

const includeModules = [
'react-native-animatable',
Expand Down
4 changes: 2 additions & 2 deletions desktop/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ const manuallyCheckForUpdates = (menuItem?: MenuItem, browserWindow?: BrowserWin

autoUpdater
.checkForUpdates()
.catch((error) => {
.catch((error: unknown) => {
isSilentUpdating = false;
return {error};
})
Expand Down Expand Up @@ -617,7 +617,7 @@ const mainWindow = (): Promise<void> => {
});

const downloadQueue = createDownloadQueue();
ipcMain.on(ELECTRON_EVENTS.DOWNLOAD, (event, downloadData) => {
ipcMain.on(ELECTRON_EVENTS.DOWNLOAD, (event, downloadData: DownloadItem) => {
const downloadItem: DownloadItem = {
...downloadData,
win: browserWindow,
Expand Down
4 changes: 2 additions & 2 deletions jest/setup.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import '@shopify/flash-list/jestSetup';
import 'react-native-gesture-handler/jestSetup';
import type * as RNKeyboardController from 'react-native-keyboard-controller';
import mockStorage from 'react-native-onyx/dist/storage/__mocks__';
import 'setimmediate';
import mockFSLibrary from './setupMockFullstoryLib';
Expand Down Expand Up @@ -54,5 +55,4 @@ jest.mock('react-native-share', () => ({
default: jest.fn(),
}));

// eslint-disable-next-line @typescript-eslint/no-unsafe-return
jest.mock('react-native-keyboard-controller', () => require('react-native-keyboard-controller/jest'));
jest.mock('react-native-keyboard-controller', () => require<typeof RNKeyboardController>('react-native-keyboard-controller/jest'));
2 changes: 1 addition & 1 deletion jest/setupMockFullstoryLib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export default function mockFSLibrary() {
return {
FSPage(): FSPageInterface {
return {
start: jest.fn(),
start: jest.fn(() => {}),
};
},
default: Fullstory,
Expand Down
2 changes: 1 addition & 1 deletion src/components/AttachmentModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ function AttachmentModal({
}
let fileObject = data;
if ('getAsFile' in data && typeof data.getAsFile === 'function') {
fileObject = data.getAsFile();
fileObject = data.getAsFile() as FileObject;
}
if (!fileObject) {
return;
Expand Down
2 changes: 1 addition & 1 deletion src/components/Attachments/AttachmentCarousel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ function AttachmentCarousel({report, reportActions, parentReportActions, source,
return;
}

const item: Attachment = entry.item;
const item = entry.item as Attachment;
if (entry.index !== null) {
setPage(entry.index);
setActiveSource(item.source);
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 @@ -251,7 +251,7 @@ function Composer(
}, []);

useEffect(() => {
const scrollingListener = DeviceEventEmitter.addListener(CONST.EVENTS.SCROLLING, (scrolling) => {
const scrollingListener = DeviceEventEmitter.addListener(CONST.EVENTS.SCROLLING, (scrolling: boolean) => {
isReportFlatListScrolling.current = scrolling;
});

Expand Down
1 change: 0 additions & 1 deletion src/components/FlatList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ function MVCPFlatList<TItem>({maintainVisibleContentPosition, horizontal = false
return horizontal ? getScrollableNode(scrollRef.current)?.scrollLeft ?? 0 : getScrollableNode(scrollRef.current)?.scrollTop ?? 0;
}, [horizontal]);

// eslint-disable-next-line @typescript-eslint/no-unsafe-return
blazejkustra marked this conversation as resolved.
Show resolved Hide resolved
const getContentView = useCallback(() => getScrollableNode(scrollRef.current)?.childNodes[0], []);

const scrollToOffset = useCallback(
Expand Down
4 changes: 2 additions & 2 deletions src/components/Hoverable/ActiveHoverable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ function ActiveHoverable({onHoverIn, onHoverOut, shouldHandleScroll, shouldFreez
return;
}

const scrollingListener = DeviceEventEmitter.addListener(CONST.EVENTS.SCROLLING, (scrolling) => {
const scrollingListener = DeviceEventEmitter.addListener(CONST.EVENTS.SCROLLING, (scrolling: boolean) => {
isScrollingRef.current = scrolling;
if (!isScrollingRef.current) {
setIsHovered(isHoveredRef.current);
Expand Down Expand Up @@ -102,7 +102,7 @@ function ActiveHoverable({onHoverIn, onHoverOut, shouldHandleScroll, shouldFreez

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

const {onMouseEnter, onMouseLeave, onMouseMove, onBlur}: OnMouseEvents = child.props;
const {onMouseEnter, onMouseLeave, onMouseMove, onBlur} = child.props as OnMouseEvents;

const hoverAndForwardOnMouseEnter = useCallback(
(e: MouseEvent) => {
Expand Down
2 changes: 1 addition & 1 deletion src/components/IFrame.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ function getNewDotURL(url: string): string {

let params: Record<string, string>;
try {
params = JSON.parse(paramString);
params = JSON.parse(paramString) as Record<string, string>;
} catch {
params = {};
}
Expand Down
29 changes: 15 additions & 14 deletions src/components/LottieAnimations/index.tsx
Original file line number Diff line number Diff line change
@@ -1,80 +1,81 @@
import type {LottieViewProps} from 'lottie-react-native';
import colors from '@styles/theme/colors';
import variables from '@styles/variables';
import type DotLottieAnimation from './types';

const DotLottieAnimations = {
Abracadabra: {
file: require('@assets/animations/Abracadabra.lottie'),
file: require<LottieViewProps['source']>('@assets/animations/Abracadabra.lottie'),
blazejkustra marked this conversation as resolved.
Show resolved Hide resolved
w: 375,
h: 400,
},
FastMoney: {
file: require('@assets/animations/FastMoney.lottie'),
file: require<LottieViewProps['source']>('@assets/animations/FastMoney.lottie'),
w: 375,
h: 240,
},
Fireworks: {
file: require('@assets/animations/Fireworks.lottie'),
file: require<LottieViewProps['source']>('@assets/animations/Fireworks.lottie'),
w: 360,
h: 360,
},
Hands: {
file: require('@assets/animations/Hands.lottie'),
file: require<LottieViewProps['source']>('@assets/animations/Hands.lottie'),
w: 375,
h: 375,
},
PreferencesDJ: {
file: require('@assets/animations/PreferencesDJ.lottie'),
file: require<LottieViewProps['source']>('@assets/animations/PreferencesDJ.lottie'),
w: 375,
h: 240,
backgroundColor: colors.blue500,
},
ReviewingBankInfo: {
file: require('@assets/animations/ReviewingBankInfo.lottie'),
file: require<LottieViewProps['source']>('@assets/animations/ReviewingBankInfo.lottie'),
w: 280,
h: 280,
},
WorkspacePlanet: {
file: require('@assets/animations/WorkspacePlanet.lottie'),
file: require<LottieViewProps['source']>('@assets/animations/WorkspacePlanet.lottie'),
w: 375,
h: 240,
backgroundColor: colors.pink800,
},
SaveTheWorld: {
file: require('@assets/animations/SaveTheWorld.lottie'),
file: require<LottieViewProps['source']>('@assets/animations/SaveTheWorld.lottie'),
w: 375,
h: 240,
},
Safe: {
file: require('@assets/animations/Safe.lottie'),
file: require<LottieViewProps['source']>('@assets/animations/Safe.lottie'),
w: 625,
h: 400,
backgroundColor: colors.ice500,
},
Magician: {
file: require('@assets/animations/Magician.lottie'),
file: require<LottieViewProps['source']>('@assets/animations/Magician.lottie'),
w: 853,
h: 480,
},
Update: {
file: require('@assets/animations/Update.lottie'),
file: require<LottieViewProps['source']>('@assets/animations/Update.lottie'),
w: variables.updateAnimationW,
h: variables.updateAnimationH,
},
Coin: {
file: require('@assets/animations/Coin.lottie'),
file: require<LottieViewProps['source']>('@assets/animations/Coin.lottie'),
w: 375,
h: 240,
backgroundColor: colors.yellow600,
},
Desk: {
file: require('@assets/animations/Desk.lottie'),
file: require<LottieViewProps['source']>('@assets/animations/Desk.lottie'),
w: 200,
h: 120,
backgroundColor: colors.blue700,
},
Plane: {
file: require('@assets/animations/Plane.lottie'),
file: require<LottieViewProps['source']>('@assets/animations/Plane.lottie'),
w: 180,
h: 200,
},
Expand Down
2 changes: 1 addition & 1 deletion src/components/MagicCodeInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ function MagicCodeInput(

// Fill the array with empty characters if there are no inputs.
if (focusedIndex === 0 && !hasInputs) {
numbers = Array(maxLength).fill(CONST.MAGIC_CODE_EMPTY_CHAR);
numbers = Array<string>(maxLength).fill(CONST.MAGIC_CODE_EMPTY_CHAR);

// Deletes the value of the previous input and focuses on it.
} else if (focusedIndex && focusedIndex !== 0) {
Expand Down
9 changes: 5 additions & 4 deletions src/components/OfflineWithFeedback.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {mapValues} from 'lodash';
import React, {useCallback} from 'react';
import type {ImageStyle, StyleProp, TextStyle, ViewStyle} from 'react-native';
import type {StyleProp, ViewStyle} from 'react-native';
import {View} from 'react-native';
import useNetwork from '@hooks/useNetwork';
import useStyleUtils from '@hooks/useStyleUtils';
Expand Down Expand Up @@ -60,7 +60,7 @@ type OfflineWithFeedbackProps = ChildrenProps & {
canDismissError?: boolean;
};

type StrikethroughProps = Partial<ChildrenProps> & {style: Array<ViewStyle | TextStyle | ImageStyle>};
type StrikethroughProps = Partial<ChildrenProps> & {style: AllStyles[]};

function OfflineWithFeedback({
pendingAction,
Expand Down Expand Up @@ -107,9 +107,10 @@ function OfflineWithFeedback({
return child;
}

const childProps: {children: React.ReactNode | undefined; style: AllStyles} = child.props;
type ChildComponentProps = ChildrenProps & {style?: AllStyles};
const childProps = child.props as ChildComponentProps;
const props: StrikethroughProps = {
style: StyleUtils.combineStyles(childProps.style, styles.offlineFeedback.deleted, styles.userSelectNone),
style: StyleUtils.combineStyles(childProps.style ?? [], styles.offlineFeedback.deleted, styles.userSelectNone),
};

if (childProps.children) {
Expand Down
Loading
Loading