diff --git a/src/libs/actions/EmojiPickerAction.ts b/src/libs/actions/EmojiPickerAction.ts
index c63e1c13d29a..a54095ad9c23 100644
--- a/src/libs/actions/EmojiPickerAction.ts
+++ b/src/libs/actions/EmojiPickerAction.ts
@@ -112,4 +112,4 @@ function resetEmojiPopoverAnchor() {
 }
 
 export {emojiPickerRef, showEmojiPicker, hideEmojiPicker, isActive, clearActive, isEmojiPickerVisible, resetEmojiPopoverAnchor};
-export type {AnchorOrigin};
+export type {AnchorOrigin, EmojiPickerRef};
diff --git a/src/types/onyx/ReportAction.ts b/src/types/onyx/ReportAction.ts
index ad81ae480cd0..86383a8d0047 100644
--- a/src/types/onyx/ReportAction.ts
+++ b/src/types/onyx/ReportAction.ts
@@ -2,6 +2,8 @@ import type {ValueOf} from 'type-fest';
 import type {FileObject} from '@components/AttachmentModal';
 import type {AvatarSource} from '@libs/UserUtils';
 import type CONST from '@src/CONST';
+import type ONYXKEYS from '@src/ONYXKEYS';
+import type CollectionDataSet from '@src/types/utils/CollectionDataSet';
 import type {EmptyObject} from '@src/types/utils/EmptyObject';
 import type * as OnyxCommon from './OnyxCommon';
 import type {Decision, Reaction} from './OriginalMessage';
@@ -230,5 +232,7 @@ type ReportAction = ReportActionBase & OriginalMessage;
 
 type ReportActions = Record<string, ReportAction>;
 
+type ReportActionsCollectionDataSet = CollectionDataSet<typeof ONYXKEYS.COLLECTION.REPORT_ACTIONS>;
+
 export default ReportAction;
-export type {ReportActions, ReportActionBase, Message, LinkMetadata, OriginalMessage};
+export type {ReportActions, ReportActionBase, Message, LinkMetadata, OriginalMessage, ReportActionsCollectionDataSet};
diff --git a/tests/perf-test/ReportActionCompose.perf-test.js b/tests/perf-test/ReportActionCompose.perf-test.tsx
similarity index 76%
rename from tests/perf-test/ReportActionCompose.perf-test.js
rename to tests/perf-test/ReportActionCompose.perf-test.tsx
index 5b70666632f9..8d6cb1ac7e57 100644
--- a/tests/perf-test/ReportActionCompose.perf-test.js
+++ b/tests/perf-test/ReportActionCompose.perf-test.tsx
@@ -1,25 +1,34 @@
 import {fireEvent, screen} from '@testing-library/react-native';
+import type {ComponentType} from 'react';
 import React from 'react';
 import Onyx from 'react-native-onyx';
+import type Animated from 'react-native-reanimated';
 import {measurePerformance} from 'reassure';
-import ComposeProviders from '../../src/components/ComposeProviders';
-import {LocaleContextProvider} from '../../src/components/LocaleContextProvider';
-import OnyxProvider from '../../src/components/OnyxProvider';
-import {KeyboardStateProvider} from '../../src/components/withKeyboardState';
-import {WindowDimensionsProvider} from '../../src/components/withWindowDimensions';
-import * as Localize from '../../src/libs/Localize';
-import ONYXKEYS from '../../src/ONYXKEYS';
-import ReportActionCompose from '../../src/pages/home/report/ReportActionCompose/ReportActionCompose';
+import type {WithNavigationFocusProps} from '@components/withNavigationFocus';
+import type {EmojiPickerRef} from '@libs/actions/EmojiPickerAction';
+import type Navigation from '@libs/Navigation/Navigation';
+import ComposeProviders from '@src/components/ComposeProviders';
+import {LocaleContextProvider} from '@src/components/LocaleContextProvider';
+import OnyxProvider from '@src/components/OnyxProvider';
+import {KeyboardStateProvider} from '@src/components/withKeyboardState';
+import {WindowDimensionsProvider} from '@src/components/withWindowDimensions';
+import * as Localize from '@src/libs/Localize';
+import ONYXKEYS from '@src/ONYXKEYS';
+import ReportActionCompose from '@src/pages/home/report/ReportActionCompose/ReportActionCompose';
 import * as LHNTestUtils from '../utils/LHNTestUtils';
 import waitForBatchedUpdates from '../utils/waitForBatchedUpdates';
 
 // mock PortalStateContext
 jest.mock('@gorhom/portal');
 
-jest.mock('react-native-reanimated', () => ({
-    ...jest.requireActual('react-native-reanimated/mock'),
-    useAnimatedRef: jest.fn,
-}));
+jest.mock(
+    'react-native-reanimated',
+    () =>
+        ({
+            ...jest.requireActual('react-native-reanimated/mock'),
+            useAnimatedRef: jest.fn(),
+        } as typeof Animated),
+);
 
 jest.mock('@react-navigation/native', () => {
     const actualNav = jest.requireActual('@react-navigation/native');
@@ -32,11 +41,11 @@ jest.mock('@react-navigation/native', () => {
         useIsFocused: () => ({
             navigate: jest.fn(),
         }),
-    };
+    } as typeof Navigation;
 });
 
-jest.mock('../../src/libs/actions/EmojiPickerAction', () => {
-    const actualEmojiPickerAction = jest.requireActual('../../src/libs/actions/EmojiPickerAction');
+jest.mock('@src/libs/actions/EmojiPickerAction', () => {
+    const actualEmojiPickerAction = jest.requireActual('@src/libs/actions/EmojiPickerAction');
     return {
         ...actualEmojiPickerAction,
         emojiPickerRef: {
@@ -47,15 +56,15 @@ jest.mock('../../src/libs/actions/EmojiPickerAction', () => {
         showEmojiPicker: jest.fn(),
         hideEmojiPicker: jest.fn(),
         isActive: () => true,
-    };
+    } as EmojiPickerRef;
 });
 
-jest.mock('../../src/components/withNavigationFocus', () => (Component) => {
-    function WithNavigationFocus(props) {
+jest.mock('@src/components/withNavigationFocus', <TProps extends WithNavigationFocusProps>() => (Component: ComponentType<TProps>) => {
+    function WithNavigationFocus(props: Omit<TProps, keyof WithNavigationFocusProps>) {
         return (
             <Component
                 // eslint-disable-next-line react/jsx-props-no-spreading
-                {...props}
+                {...(props as TProps)}
                 isFocused={false}
             />
         );
@@ -70,7 +79,6 @@ beforeAll(() =>
     Onyx.init({
         keys: ONYXKEYS,
         safeEvictionKeys: [ONYXKEYS.COLLECTION.REPORT_ACTIONS],
-        registerStorageEventListener: () => {},
     }),
 );
 
@@ -87,6 +95,8 @@ function ReportActionComposeWrapper() {
                 reportID="1"
                 disabled={false}
                 report={LHNTestUtils.getFakeReport()}
+                isComposerFullSize
+                listHeight={200}
             />
         </ComposeProviders>
     );
diff --git a/tests/perf-test/ReportActionsList.perf-test.js b/tests/perf-test/ReportActionsList.perf-test.tsx
similarity index 60%
rename from tests/perf-test/ReportActionsList.perf-test.js
rename to tests/perf-test/ReportActionsList.perf-test.tsx
index 1555f2032275..012d8dc8b90f 100644
--- a/tests/perf-test/ReportActionsList.perf-test.js
+++ b/tests/perf-test/ReportActionsList.perf-test.tsx
@@ -1,17 +1,21 @@
 import {fireEvent, screen} from '@testing-library/react-native';
+import type {ComponentType} from 'react';
 import Onyx from 'react-native-onyx';
 import {measurePerformance} from 'reassure';
-import ComposeProviders from '../../src/components/ComposeProviders';
-import {LocaleContextProvider} from '../../src/components/LocaleContextProvider';
-import OnyxProvider from '../../src/components/OnyxProvider';
-import {WindowDimensionsProvider} from '../../src/components/withWindowDimensions';
-import * as Localize from '../../src/libs/Localize';
-import ONYXKEYS from '../../src/ONYXKEYS';
-import ReportActionsList from '../../src/pages/home/report/ReportActionsList';
-import {ReportAttachmentsProvider} from '../../src/pages/home/report/ReportAttachmentsContext';
-import {ActionListContext, ReactionListContext} from '../../src/pages/home/ReportScreenContext';
-import variables from '../../src/styles/variables';
-import * as LHNTestUtils from '../utils/LHNTestUtils';
+import type {WithCurrentUserPersonalDetailsProps} from '@components/withCurrentUserPersonalDetails';
+import type Navigation from '@libs/Navigation/Navigation';
+import ComposeProviders from '@src/components/ComposeProviders';
+import {LocaleContextProvider} from '@src/components/LocaleContextProvider';
+import OnyxProvider from '@src/components/OnyxProvider';
+import {WindowDimensionsProvider} from '@src/components/withWindowDimensions';
+import * as Localize from '@src/libs/Localize';
+import ONYXKEYS from '@src/ONYXKEYS';
+import ReportActionsList from '@src/pages/home/report/ReportActionsList';
+import {ReportAttachmentsProvider} from '@src/pages/home/report/ReportAttachmentsContext';
+import {ActionListContext, ReactionListContext} from '@src/pages/home/ReportScreenContext';
+import variables from '@src/styles/variables';
+import createRandomReportAction from '../utils/collections/reportActions';
+import * as LHNTestUtilsModule from '../utils/LHNTestUtils';
 import PusherHelper from '../utils/PusherHelper';
 import * as ReportTestUtils from '../utils/ReportTestUtils';
 import waitForBatchedUpdates from '../utils/waitForBatchedUpdates';
@@ -19,20 +23,29 @@ import wrapOnyxWithWaitForBatchedUpdates from '../utils/wrapOnyxWithWaitForBatch
 
 const mockedNavigate = jest.fn();
 
-jest.mock('../../src/components/withNavigationFocus', () => (Component) => {
-    function WithNavigationFocus(props) {
-        return (
-            <Component
-                // eslint-disable-next-line react/jsx-props-no-spreading
-                {...props}
-                isFocused={false}
-            />
-        );
-    }
+jest.mock('@components/withCurrentUserPersonalDetails', () => {
+    // Lazy loading of LHNTestUtils
+    // eslint-disable-next-line @typescript-eslint/no-unsafe-return
+    const lazyLoadLHNTestUtils = () => require('../utils/LHNTestUtils');
 
-    WithNavigationFocus.displayName = 'WithNavigationFocus';
+    return <TProps extends WithCurrentUserPersonalDetailsProps>(Component: ComponentType<TProps>) => {
+        function WrappedComponent(props: Omit<TProps, keyof WithCurrentUserPersonalDetailsProps>) {
+            const currentUserAccountID = 5;
+            const LHNTestUtils = lazyLoadLHNTestUtils(); // Load LHNTestUtils here
 
-    return WithNavigationFocus;
+            return (
+                <Component
+                    // eslint-disable-next-line react/jsx-props-no-spreading
+                    {...(props as TProps)}
+                    currentUserPersonalDetails={LHNTestUtils.fakePersonalDetails[currentUserAccountID]}
+                />
+            );
+        }
+
+        WrappedComponent.displayName = 'WrappedComponent';
+
+        return WrappedComponent;
+    };
 });
 
 jest.mock('@react-navigation/native', () => {
@@ -41,16 +54,15 @@ jest.mock('@react-navigation/native', () => {
         ...actualNav,
         useRoute: () => mockedNavigate,
         useIsFocused: () => true,
-    };
+    } as typeof Navigation;
 });
 
-jest.mock('../../src/components/ConfirmedRoute.tsx');
+jest.mock('@src/components/ConfirmedRoute.tsx');
 
 beforeAll(() =>
     Onyx.init({
         keys: ONYXKEYS,
         safeEvictionKeys: [ONYXKEYS.COLLECTION.REPORT_ACTIONS],
-        registerStorageEventListener: () => {},
     }),
 );
 
@@ -61,7 +73,7 @@ afterAll(() => {
 const mockOnLayout = jest.fn();
 const mockOnScroll = jest.fn();
 const mockLoadChats = jest.fn();
-const mockRef = {current: null};
+const mockRef = {current: null, flatListRef: null, scrollPosition: null, setScrollPosition: () => {}};
 
 // Initialize the network key for OfflineWithFeedback
 beforeEach(() => {
@@ -76,22 +88,21 @@ afterEach(() => {
     PusherHelper.teardown();
 });
 
-const currentUserAccountID = 5;
-
 function ReportActionsListWrapper() {
     return (
         <ComposeProviders components={[OnyxProvider, LocaleContextProvider, WindowDimensionsProvider, ReportAttachmentsProvider]}>
             <ReactionListContext.Provider value={mockRef}>
                 <ActionListContext.Provider value={mockRef}>
                     <ReportActionsList
+                        parentReportAction={createRandomReportAction(1)}
                         sortedReportActions={ReportTestUtils.getMockedSortedReportActions(500)}
-                        report={LHNTestUtils.getFakeReport()}
+                        report={LHNTestUtilsModule.getFakeReport()}
                         onLayout={mockOnLayout}
                         onScroll={mockOnScroll}
-                        loadMoreChats={mockLoadChats}
+                        onContentSizeChange={() => {}}
+                        listID={1}
                         loadOlderChats={mockLoadChats}
                         loadNewerChats={mockLoadChats}
-                        currentUserPersonalDetails={LHNTestUtils.fakePersonalDetails[currentUserAccountID]}
                     />
                 </ActionListContext.Provider>
             </ReactionListContext.Provider>
@@ -110,7 +121,7 @@ test('[ReportActionsList] should render ReportActionsList with 500 reportActions
     return waitForBatchedUpdates()
         .then(() =>
             Onyx.multiSet({
-                [ONYXKEYS.PERSONAL_DETAILS_LIST]: LHNTestUtils.fakePersonalDetails,
+                [ONYXKEYS.PERSONAL_DETAILS_LIST]: LHNTestUtilsModule.fakePersonalDetails,
             }),
         )
         .then(() => measurePerformance(<ReportActionsListWrapper />, {scenario}));
@@ -148,7 +159,7 @@ test('[ReportActionsList] should scroll and click some of the reports', () => {
     return waitForBatchedUpdates()
         .then(() =>
             Onyx.multiSet({
-                [ONYXKEYS.PERSONAL_DETAILS_LIST]: LHNTestUtils.fakePersonalDetails,
+                [ONYXKEYS.PERSONAL_DETAILS_LIST]: LHNTestUtilsModule.fakePersonalDetails,
             }),
         )
         .then(() => measurePerformance(<ReportActionsListWrapper />, {scenario}));
diff --git a/tests/perf-test/ReportScreen.perf-test.js b/tests/perf-test/ReportScreen.perf-test.tsx
similarity index 61%
rename from tests/perf-test/ReportScreen.perf-test.js
rename to tests/perf-test/ReportScreen.perf-test.tsx
index bc127ff8a1f1..b79a6916b7cf 100644
--- a/tests/perf-test/ReportScreen.perf-test.js
+++ b/tests/perf-test/ReportScreen.perf-test.tsx
@@ -1,19 +1,29 @@
+import type {StackScreenProps} from '@react-navigation/stack';
 import {fireEvent, screen, waitFor} from '@testing-library/react-native';
+import type {ComponentType} from 'react';
 import React from 'react';
 import Onyx from 'react-native-onyx';
+import type Animated from 'react-native-reanimated';
 import {measurePerformance} from 'reassure';
-import ComposeProviders from '../../src/components/ComposeProviders';
-import DragAndDropProvider from '../../src/components/DragAndDrop/Provider';
-import {LocaleContextProvider} from '../../src/components/LocaleContextProvider';
-import OnyxProvider from '../../src/components/OnyxProvider';
-import {CurrentReportIDContextProvider} from '../../src/components/withCurrentReportID';
-import {KeyboardStateProvider} from '../../src/components/withKeyboardState';
-import {WindowDimensionsProvider} from '../../src/components/withWindowDimensions';
-import CONST from '../../src/CONST';
-import * as Localize from '../../src/libs/Localize';
-import ONYXKEYS from '../../src/ONYXKEYS';
-import {ReportAttachmentsProvider} from '../../src/pages/home/report/ReportAttachmentsContext';
-import ReportScreen from '../../src/pages/home/ReportScreen';
+import type {WithNavigationFocusProps} from '@components/withNavigationFocus';
+import type Navigation from '@libs/Navigation/Navigation';
+import type {CentralPaneNavigatorParamList} from '@libs/Navigation/types';
+import ComposeProviders from '@src/components/ComposeProviders';
+import DragAndDropProvider from '@src/components/DragAndDrop/Provider';
+import {LocaleContextProvider} from '@src/components/LocaleContextProvider';
+import OnyxProvider from '@src/components/OnyxProvider';
+import {CurrentReportIDContextProvider} from '@src/components/withCurrentReportID';
+import {KeyboardStateProvider} from '@src/components/withKeyboardState';
+import {WindowDimensionsProvider} from '@src/components/withWindowDimensions';
+import CONST from '@src/CONST';
+import * as Localize from '@src/libs/Localize';
+import ONYXKEYS from '@src/ONYXKEYS';
+import {ReportAttachmentsProvider} from '@src/pages/home/report/ReportAttachmentsContext';
+import ReportScreen from '@src/pages/home/ReportScreen';
+import type SCREENS from '@src/SCREENS';
+import type * as OnyxTypes from '@src/types/onyx';
+import type {ReportCollectionDataSet} from '@src/types/onyx/Report';
+import type {ReportActionsCollectionDataSet} from '@src/types/onyx/ReportAction';
 import createCollection from '../utils/collections/createCollection';
 import createPersonalDetails from '../utils/collections/personalDetails';
 import createRandomPolicy from '../utils/collections/policies';
@@ -24,21 +34,26 @@ import * as TestHelper from '../utils/TestHelper';
 import waitForBatchedUpdates from '../utils/waitForBatchedUpdates';
 import wrapOnyxWithWaitForBatchedUpdates from '../utils/wrapOnyxWithWaitForBatchedUpdates';
 
-jest.mock('react-native-reanimated', () => ({
-    ...jest.requireActual('react-native-reanimated/mock'),
-    useSharedValue: jest.fn,
-    useAnimatedStyle: jest.fn,
-    useAnimatedRef: jest.fn,
-}));
+type ReportScreenWrapperProps = StackScreenProps<CentralPaneNavigatorParamList, typeof SCREENS.REPORT>;
+
+jest.mock('react-native-reanimated', () => {
+    const actualNav = jest.requireActual('react-native-reanimated/mock');
+    return {
+        ...actualNav,
+        useSharedValue: jest.fn,
+        useAnimatedStyle: jest.fn,
+        useAnimatedRef: jest.fn,
+    } as typeof Animated;
+});
 
-jest.mock('../../src/components/ConfirmedRoute.tsx');
+jest.mock('@src/components/ConfirmedRoute.tsx');
 
-jest.mock('../../src/components/withNavigationFocus', () => (Component) => {
-    function WithNavigationFocus(props) {
+jest.mock('@src/components/withNavigationFocus', <TProps extends WithNavigationFocusProps>() => (Component: ComponentType<TProps>) => {
+    function WithNavigationFocus(props: Omit<TProps, keyof WithNavigationFocusProps>) {
         return (
             <Component
                 // eslint-disable-next-line react/jsx-props-no-spreading
-                {...props}
+                {...(props as TProps)}
                 isFocused={false}
             />
         );
@@ -49,7 +64,7 @@ jest.mock('../../src/components/withNavigationFocus', () => (Component) => {
     return WithNavigationFocus;
 });
 
-jest.mock('../../src/hooks/useEnvironment', () =>
+jest.mock('@src/hooks/useEnvironment', () =>
     jest.fn(() => ({
         environment: 'development',
         environmentURL: 'https://new.expensify.com',
@@ -58,13 +73,13 @@ jest.mock('../../src/hooks/useEnvironment', () =>
     })),
 );
 
-jest.mock('../../src/libs/Permissions', () => ({
+jest.mock('@src/libs/Permissions', () => ({
     canUseLinkPreviews: jest.fn(() => true),
     canUseDefaultRooms: jest.fn(() => true),
 }));
-jest.mock('../../src/hooks/usePermissions.ts');
+jest.mock('@src/hooks/usePermissions.ts');
 
-jest.mock('../../src/libs/Navigation/Navigation');
+jest.mock('@src/libs/Navigation/Navigation');
 
 const mockedNavigate = jest.fn();
 jest.mock('@react-navigation/native', () => {
@@ -81,7 +96,7 @@ jest.mock('@react-navigation/native', () => {
             addListener: () => jest.fn(),
         }),
         createNavigationContainerRef: jest.fn(),
-    };
+    } as typeof Navigation;
 });
 
 // mock PortalStateContext
@@ -91,12 +106,12 @@ beforeAll(() =>
     Onyx.init({
         keys: ONYXKEYS,
         safeEvictionKeys: [ONYXKEYS.COLLECTION.REPORT_ACTIONS],
-        registerStorageEventListener: () => {},
     }),
 );
 
 // Initialize the network key for OfflineWithFeedback
 beforeEach(() => {
+    // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
     global.fetch = TestHelper.getGlobalFetchMock();
     wrapOnyxWithWaitForBatchedUpdates(Onyx);
     Onyx.merge(ONYXKEYS.NETWORK, {isOffline: false});
@@ -109,18 +124,18 @@ afterEach(() => {
 });
 
 const policies = createCollection(
-    (item) => `${ONYXKEYS.COLLECTION.POLICY}${item.id}`,
-    (index) => createRandomPolicy(index),
+    (item: OnyxTypes.Policy) => `${ONYXKEYS.COLLECTION.POLICY}${item.id}`,
+    (index: number) => createRandomPolicy(index),
     10,
 );
 
 const personalDetails = createCollection(
-    (item) => item.accountID,
-    (index) => createPersonalDetails(index),
+    (item: OnyxTypes.PersonalDetails) => item.accountID,
+    (index: number) => createPersonalDetails(index),
     20,
 );
 
-function ReportScreenWrapper(args) {
+function ReportScreenWrapper(props: ReportScreenWrapperProps) {
     return (
         <ComposeProviders
             components={[
@@ -135,8 +150,9 @@ function ReportScreenWrapper(args) {
         >
             <ReportScreen
                 // eslint-disable-next-line react/jsx-props-no-spreading
-                {...args}
-                navigation={args.navigation}
+                {...props}
+                route={props.route}
+                navigation={props.navigation}
             />
         </ComposeProviders>
     );
@@ -147,6 +163,7 @@ const reportActions = ReportTestUtils.getMockedReportActionsMap(500);
 const mockRoute = {params: {reportID: '1'}};
 
 test('[ReportScreen] should render ReportScreen with composer interactions', () => {
+    // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
     const {triggerTransitionEnd, addListener} = TestHelper.createAddListenerMock();
     const scenario = async () => {
         /**
@@ -182,21 +199,31 @@ test('[ReportScreen] should render ReportScreen with composer interactions', ()
     const navigation = {addListener};
 
     return waitForBatchedUpdates()
-        .then(() =>
-            Onyx.multiSet({
-                [ONYXKEYS.IS_SIDEBAR_LOADED]: true,
+        .then(() => {
+            const reportCollectionDataSet: ReportCollectionDataSet = {
                 [`${ONYXKEYS.COLLECTION.REPORT}${mockRoute.params.reportID}`]: report,
+            };
+
+            const reportActionsCollectionDataSet: ReportActionsCollectionDataSet = {
                 [`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${mockRoute.params.reportID}`]: reportActions,
+            };
+
+            return Onyx.multiSet({
+                [ONYXKEYS.IS_SIDEBAR_LOADED]: true,
                 [ONYXKEYS.PERSONAL_DETAILS_LIST]: personalDetails,
                 [ONYXKEYS.BETAS]: [CONST.BETAS.DEFAULT_ROOMS],
                 [`${ONYXKEYS.COLLECTION.POLICY}`]: policies,
                 [ONYXKEYS.SHOULD_SHOW_COMPOSE_INPUT]: true,
-            }),
-        )
+                ...reportCollectionDataSet,
+                ...reportActionsCollectionDataSet,
+            });
+        })
         .then(() =>
             measurePerformance(
                 <ReportScreenWrapper
+                    // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
                     navigation={navigation}
+                    // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
                     route={mockRoute}
                 />,
                 {scenario},
@@ -205,6 +232,7 @@ test('[ReportScreen] should render ReportScreen with composer interactions', ()
 });
 
 test('[ReportScreen] should press of the report item', () => {
+    // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
     const {triggerTransitionEnd, addListener} = TestHelper.createAddListenerMock();
     const scenario = async () => {
         /**
@@ -232,20 +260,30 @@ test('[ReportScreen] should press of the report item', () => {
     const navigation = {addListener};
 
     return waitForBatchedUpdates()
-        .then(() =>
-            Onyx.multiSet({
-                [ONYXKEYS.IS_SIDEBAR_LOADED]: true,
+        .then(() => {
+            const reportCollectionDataSet: ReportCollectionDataSet = {
                 [`${ONYXKEYS.COLLECTION.REPORT}${mockRoute.params.reportID}`]: report,
+            };
+
+            const reportActionsCollectionDataSet: ReportActionsCollectionDataSet = {
                 [`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${mockRoute.params.reportID}`]: reportActions,
+            };
+
+            return Onyx.multiSet({
+                [ONYXKEYS.IS_SIDEBAR_LOADED]: true,
                 [ONYXKEYS.PERSONAL_DETAILS_LIST]: personalDetails,
                 [ONYXKEYS.BETAS]: [CONST.BETAS.DEFAULT_ROOMS],
                 [`${ONYXKEYS.COLLECTION.POLICY}`]: policies,
-            }),
-        )
+                ...reportCollectionDataSet,
+                ...reportActionsCollectionDataSet,
+            });
+        })
         .then(() =>
             measurePerformance(
                 <ReportScreenWrapper
+                    // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
                     navigation={navigation}
+                    // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
                     route={mockRoute}
                 />,
                 {scenario},
diff --git a/tests/unit/MiddlewareTest.js b/tests/unit/MiddlewareTest.ts
similarity index 69%
rename from tests/unit/MiddlewareTest.js
rename to tests/unit/MiddlewareTest.ts
index 6a9576511f38..b3ba6d32a7bb 100644
--- a/tests/unit/MiddlewareTest.js
+++ b/tests/unit/MiddlewareTest.ts
@@ -1,10 +1,11 @@
 import Onyx from 'react-native-onyx';
-import HttpUtils from '../../src/libs/HttpUtils';
-import * as MainQueue from '../../src/libs/Network/MainQueue';
-import * as NetworkStore from '../../src/libs/Network/NetworkStore';
-import * as SequentialQueue from '../../src/libs/Network/SequentialQueue';
-import * as Request from '../../src/libs/Request';
-import ONYXKEYS from '../../src/ONYXKEYS';
+import HttpUtils from '@src/libs/HttpUtils';
+import handleUnusedOptimisticID from '@src/libs/Middleware/HandleUnusedOptimisticID';
+import * as MainQueue from '@src/libs/Network/MainQueue';
+import * as NetworkStore from '@src/libs/Network/NetworkStore';
+import * as SequentialQueue from '@src/libs/Network/SequentialQueue';
+import * as Request from '@src/libs/Request';
+import ONYXKEYS from '@src/ONYXKEYS';
 import * as TestHelper from '../utils/TestHelper';
 import waitForNetworkPromises from '../utils/waitForNetworkPromises';
 
@@ -13,6 +14,7 @@ Onyx.init({
 });
 
 beforeAll(() => {
+    // @ts-expect-error TODO: Remove this once TestHelper (https://github.com/Expensify/App/issues/25318) is migrated to TypeScript.
     global.fetch = TestHelper.getGlobalFetchMock();
 });
 
@@ -29,8 +31,6 @@ beforeEach(async () => {
 describe('Middleware', () => {
     describe('HandleUnusedOptimisticID', () => {
         test('Normal request', async () => {
-            const actual = jest.requireActual('../../src/libs/Middleware/HandleUnusedOptimisticID');
-            const handleUnusedOptimisticID = jest.spyOn(actual, 'default');
             Request.use(handleUnusedOptimisticID);
             const requests = [
                 {
@@ -50,14 +50,12 @@ describe('Middleware', () => {
 
             expect(global.fetch).toHaveBeenCalledTimes(2);
             expect(global.fetch).toHaveBeenLastCalledWith('https://www.expensify.com.dev/api/AddComment?', expect.anything());
-            TestHelper.assertFormDataMatchesObject(global.fetch.mock.calls[1][1].body, {reportID: '1234', reportActionID: '5678', reportComment: 'foo'});
+            TestHelper.assertFormDataMatchesObject((global.fetch as jest.Mock).mock.calls[1][1].body, {reportID: '1234', reportActionID: '5678', reportComment: 'foo'});
             expect(global.fetch).toHaveBeenNthCalledWith(1, 'https://www.expensify.com.dev/api/OpenReport?', expect.anything());
-            TestHelper.assertFormDataMatchesObject(global.fetch.mock.calls[0][1].body, {reportID: '1234'});
+            TestHelper.assertFormDataMatchesObject((global.fetch as jest.Mock).mock.calls[0][1].body, {reportID: '1234'});
         });
 
         test('Request with preexistingReportID', async () => {
-            const actual = jest.requireActual('../../src/libs/Middleware/HandleUnusedOptimisticID');
-            const handleUnusedOptimisticID = jest.spyOn(actual, 'default');
             Request.use(handleUnusedOptimisticID);
             const requests = [
                 {
@@ -73,8 +71,10 @@ describe('Middleware', () => {
                 SequentialQueue.push(request);
             }
 
-            global.fetch.mockImplementationOnce(async () => ({
+            // eslint-disable-next-line @typescript-eslint/require-await
+            (global.fetch as jest.Mock).mockImplementationOnce(async () => ({
                 ok: true,
+                // eslint-disable-next-line @typescript-eslint/require-await
                 json: async () => ({
                     jsonCode: 200,
                     onyxData: [
@@ -94,9 +94,9 @@ describe('Middleware', () => {
 
             expect(global.fetch).toHaveBeenCalledTimes(2);
             expect(global.fetch).toHaveBeenLastCalledWith('https://www.expensify.com.dev/api/AddComment?', expect.anything());
-            TestHelper.assertFormDataMatchesObject(global.fetch.mock.calls[1][1].body, {reportID: '5555', reportActionID: '5678', reportComment: 'foo'});
+            TestHelper.assertFormDataMatchesObject((global.fetch as jest.Mock).mock.calls[1][1].body, {reportID: '5555', reportActionID: '5678', reportComment: 'foo'});
             expect(global.fetch).toHaveBeenNthCalledWith(1, 'https://www.expensify.com.dev/api/OpenReport?', expect.anything());
-            TestHelper.assertFormDataMatchesObject(global.fetch.mock.calls[0][1].body, {reportID: '1234'});
+            TestHelper.assertFormDataMatchesObject((global.fetch as jest.Mock).mock.calls[0][1].body, {reportID: '1234'});
         });
     });
 });
diff --git a/tests/unit/markPullRequestsAsDeployedTest.js b/tests/unit/markPullRequestsAsDeployedTest.ts
similarity index 78%
rename from tests/unit/markPullRequestsAsDeployedTest.js
rename to tests/unit/markPullRequestsAsDeployedTest.ts
index a401a9f96a67..3d024982c21d 100644
--- a/tests/unit/markPullRequestsAsDeployedTest.js
+++ b/tests/unit/markPullRequestsAsDeployedTest.ts
@@ -1,10 +1,39 @@
+/* eslint-disable @typescript-eslint/naming-convention */
+
 /**
  * @jest-environment node
  */
-import _ from 'underscore';
 import GithubUtils from '../../.github/libs/GithubUtils';
 import GitUtils from '../../.github/libs/GitUtils';
 
+type ObjectMethodData<T> = {
+    data: T;
+};
+
+type PullRequest = {
+    issue_number: number;
+    title: string;
+    merged_by: {login: string};
+};
+
+type PullRequestParams = {
+    pull_number: number;
+};
+
+type PullRequestData = {
+    data?: PullRequest;
+};
+
+type Commit = {
+    commit_sha: string;
+};
+
+type CommitData = {
+    data: {
+        message: string;
+    };
+};
+
 let run;
 
 const mockGetInput = jest.fn();
@@ -12,8 +41,10 @@ const mockGetPullRequest = jest.fn();
 const mockCreateComment = jest.fn();
 const mockListTags = jest.fn();
 const mockGetCommit = jest.fn();
-let workflowRunURL;
-const PRList = {
+
+let workflowRunURL: string | null;
+
+const PRList: Record<number, PullRequest> = {
     1: {
         issue_number: 1,
         title: 'Test PR 1',
@@ -35,15 +66,10 @@ const defaultTags = [
     {name: '42.42.42-41', commit: {sha: 'efgh'}},
 ];
 
-/**
- * @param {String} key
- * @returns {Boolean|String}
- * @throws {Error}
- */
-function mockGetInputDefaultImplementation(key) {
+function mockGetInputDefaultImplementation(key: string): boolean | string {
     switch (key) {
         case 'PR_LIST':
-            return JSON.stringify(_.keys(PRList));
+            return JSON.stringify(Object.keys(PRList));
         case 'IS_PRODUCTION_DEPLOY':
             return false;
         case 'DEPLOY_VERSION':
@@ -58,11 +84,7 @@ function mockGetInputDefaultImplementation(key) {
     }
 }
 
-/**
- * @param {String} sha
- * @returns {Promise<{data: {message: String}}>}
- */
-async function mockGetCommitDefaultImplementation({commit_sha}) {
+function mockGetCommitDefaultImplementation({commit_sha}: Commit): CommitData {
     if (commit_sha === 'abcd') {
         return {data: {message: 'Test commit 1'}};
     }
@@ -80,6 +102,7 @@ beforeAll(() => {
     const moctokit = {
         rest: {
             issues: {
+                // eslint-disable-next-line @typescript-eslint/require-await
                 listForRepo: jest.fn().mockImplementation(async () => ({
                     data: [
                         {
@@ -87,6 +110,7 @@ beforeAll(() => {
                         },
                     ],
                 })),
+                // eslint-disable-next-line @typescript-eslint/require-await
                 listEvents: jest.fn().mockImplementation(async () => ({
                     data: [{event: 'closed', actor: {login: 'thor'}}],
                 })),
@@ -102,18 +126,20 @@ beforeAll(() => {
                 getCommit: mockGetCommit,
             },
         },
-        paginate: jest.fn().mockImplementation((objectMethod) => objectMethod().then(({data}) => data)),
+        paginate: jest.fn().mockImplementation(<T>(objectMethod: () => Promise<ObjectMethodData<T>>) => objectMethod().then(({data}) => data)),
     };
+
+    // @ts-expect-error TODO: Remove this once GithubUtils (https://github.com/Expensify/App/issues/25382) is migrated to TypeScript.
     GithubUtils.internalOctokit = moctokit;
 
     // Mock GitUtils
     GitUtils.getPullRequestsMergedBetween = jest.fn();
 
     jest.mock('../../.github/libs/ActionUtils', () => ({
-        getJSONInput: jest.fn().mockImplementation((name, defaultValue) => {
+        getJSONInput: jest.fn().mockImplementation((name: string, defaultValue: string) => {
             try {
-                const input = mockGetInput(name);
-                return JSON.parse(input);
+                const input: string = mockGetInput(name);
+                return JSON.parse(input) as unknown;
             } catch (err) {
                 return defaultValue;
             }
@@ -123,12 +149,12 @@ beforeAll(() => {
     // Set GH runner environment variables
     process.env.GITHUB_SERVER_URL = 'https://github.com';
     process.env.GITHUB_REPOSITORY = 'Expensify/App';
-    process.env.GITHUB_RUN_ID = 1234;
+    process.env.GITHUB_RUN_ID = '1234';
     workflowRunURL = `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`;
 });
 
 beforeEach(() => {
-    mockGetPullRequest.mockImplementation(async ({pull_number}) => (pull_number in PRList ? {data: PRList[pull_number]} : {}));
+    mockGetPullRequest.mockImplementation(({pull_number}: PullRequestParams): PullRequestData => (pull_number in PRList ? {data: PRList[pull_number]} : {}));
     mockListTags.mockResolvedValue({
         data: defaultTags,
     });
@@ -150,8 +176,8 @@ describe('markPullRequestsAsDeployed', () => {
         // Note: we import this in here so that it executes after all the mocks are set up
         run = require('../../.github/actions/javascript/markPullRequestsAsDeployed/markPullRequestsAsDeployed');
         await run();
-        expect(mockCreateComment).toHaveBeenCalledTimes(_.keys(PRList).length);
-        for (let i = 0; i < _.keys(PRList).length; i++) {
+        expect(mockCreateComment).toHaveBeenCalledTimes(Object.keys(PRList).length);
+        for (let i = 0; i < Object.keys(PRList).length; i++) {
             const PR = PRList[i + 1];
             expect(mockCreateComment).toHaveBeenNthCalledWith(i + 1, {
                 body: `🚀 [Deployed](${workflowRunURL}) to staging by https://github.com/${PR.merged_by.login} in version: ${version} 🚀
@@ -181,8 +207,8 @@ platform | result
         run = require('../../.github/actions/javascript/markPullRequestsAsDeployed/markPullRequestsAsDeployed');
 
         await run();
-        expect(mockCreateComment).toHaveBeenCalledTimes(_.keys(PRList).length);
-        for (let i = 0; i < _.keys(PRList).length; i++) {
+        expect(mockCreateComment).toHaveBeenCalledTimes(Object.keys(PRList).length);
+        for (let i = 0; i < Object.keys(PRList).length; i++) {
             expect(mockCreateComment).toHaveBeenNthCalledWith(i + 1, {
                 body: `🚀 [Deployed](${workflowRunURL}) to production by https://github.com/thor in version: ${version} 🚀
 
@@ -209,7 +235,7 @@ platform | result
             }
             return mockGetInputDefaultImplementation(key);
         });
-        mockGetPullRequest.mockImplementation(async ({pull_number}) => {
+        mockGetPullRequest.mockImplementation(({pull_number}: PullRequestParams) => {
             if (pull_number === 3) {
                 return {
                     data: {
@@ -226,11 +252,11 @@ platform | result
         mockListTags.mockResolvedValue({
             data: [{name: '42.42.42-43', commit: {sha: 'xyz'}}, ...defaultTags],
         });
-        mockGetCommit.mockImplementation(async ({commit_sha}) => {
+        mockGetCommit.mockImplementation(({commit_sha}: Commit) => {
             if (commit_sha === 'xyz') {
                 return {data: {message: 'Test PR 3 (cherry picked from commit dagdag)', committer: {name: 'freyja'}}};
             }
-            return mockGetCommitDefaultImplementation(commit_sha);
+            return mockGetCommitDefaultImplementation({commit_sha});
         });
 
         // Note: we import this in here so that it executes after all the mocks are set up
@@ -271,8 +297,8 @@ platform | result
         // Note: we import this in here so that it executes after all the mocks are set up
         run = require('../../.github/actions/javascript/markPullRequestsAsDeployed/markPullRequestsAsDeployed');
         await run();
-        expect(mockCreateComment).toHaveBeenCalledTimes(_.keys(PRList).length);
-        for (let i = 0; i < _.keys(PRList).length; i++) {
+        expect(mockCreateComment).toHaveBeenCalledTimes(Object.keys(PRList).length);
+        for (let i = 0; i < Object.keys(PRList).length; i++) {
             const PR = PRList[i + 1];
             expect(mockCreateComment).toHaveBeenNthCalledWith(i + 1, {
                 body: `🚀 [Deployed](${workflowRunURL}) to staging by https://github.com/${PR.merged_by.login} in version: ${version} 🚀
