diff --git a/package-lock.json b/package-lock.json
index 49a80b78bc4f..0c638f5b8345 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -194,7 +194,6 @@
         "eslint-plugin-react-native-a11y": "^3.3.0",
         "eslint-plugin-storybook": "^0.5.13",
         "eslint-plugin-you-dont-need-lodash-underscore": "^6.12.0",
-        "flipper-plugin-bridgespy-client": "^0.1.9",
         "html-webpack-plugin": "^5.5.0",
         "jest": "29.4.1",
         "jest-circus": "29.4.1",
@@ -217,7 +216,7 @@
         "style-loader": "^2.0.0",
         "time-analytics-webpack-plugin": "^0.1.17",
         "type-fest": "^3.12.0",
-        "typescript": "^4.8.4",
+        "typescript": "^5.1.6",
         "wait-port": "^0.2.9",
         "webpack": "^5.76.0",
         "webpack-bundle-analyzer": "^4.5.0",
@@ -25235,6 +25234,19 @@
         "typescript": "^4.0.2"
       }
     },
+    "node_modules/config-file-ts/node_modules/typescript": {
+      "version": "4.9.5",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
+      "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
+      "dev": true,
+      "bin": {
+        "tsc": "bin/tsc",
+        "tsserver": "bin/tsserver"
+      },
+      "engines": {
+        "node": ">=4.2.0"
+      }
+    },
     "node_modules/confusing-browser-globals": {
       "version": "1.0.11",
       "dev": true,
@@ -30304,16 +30316,6 @@
       "dev": true,
       "license": "ISC"
     },
-    "node_modules/flipper-plugin-bridgespy-client": {
-      "version": "0.1.9",
-      "dev": true,
-      "license": "MIT",
-      "peerDependencies": {
-        "react-native": ">=0.62.0",
-        "react-native-flipper": ">=0.54.0 <1.0.0",
-        "typescript": ">=3.5.0 <5.0.0"
-      }
-    },
     "node_modules/flow-enums-runtime": {
       "version": "0.0.5",
       "resolved": "https://registry.npmjs.org/flow-enums-runtime/-/flow-enums-runtime-0.0.5.tgz",
@@ -48112,16 +48114,16 @@
       "license": "MIT"
     },
     "node_modules/typescript": {
-      "version": "4.8.4",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz",
-      "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==",
+      "version": "5.1.6",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz",
+      "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==",
       "dev": true,
       "bin": {
         "tsc": "bin/tsc",
         "tsserver": "bin/tsserver"
       },
       "engines": {
-        "node": ">=4.2.0"
+        "node": ">=14.17"
       }
     },
     "node_modules/typewise": {
@@ -67878,6 +67880,14 @@
       "requires": {
         "glob": "^7.1.6",
         "typescript": "^4.0.2"
+      },
+      "dependencies": {
+        "typescript": {
+          "version": "4.9.5",
+          "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
+          "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
+          "dev": true
+        }
       }
     },
     "confusing-browser-globals": {
@@ -71351,11 +71361,6 @@
       "version": "3.2.6",
       "dev": true
     },
-    "flipper-plugin-bridgespy-client": {
-      "version": "0.1.9",
-      "dev": true,
-      "requires": {}
-    },
     "flow-enums-runtime": {
       "version": "0.0.5",
       "resolved": "https://registry.npmjs.org/flow-enums-runtime/-/flow-enums-runtime-0.0.5.tgz",
@@ -83352,9 +83357,9 @@
       "dev": true
     },
     "typescript": {
-      "version": "4.8.4",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz",
-      "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==",
+      "version": "5.1.6",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz",
+      "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==",
       "dev": true
     },
     "typewise": {
diff --git a/package.json b/package.json
index cb86cd14f874..44ca8d7e2c1b 100644
--- a/package.json
+++ b/package.json
@@ -234,7 +234,6 @@
     "eslint-plugin-react-native-a11y": "^3.3.0",
     "eslint-plugin-storybook": "^0.5.13",
     "eslint-plugin-you-dont-need-lodash-underscore": "^6.12.0",
-    "flipper-plugin-bridgespy-client": "^0.1.9",
     "html-webpack-plugin": "^5.5.0",
     "jest": "29.4.1",
     "jest-circus": "29.4.1",
@@ -257,7 +256,7 @@
     "style-loader": "^2.0.0",
     "time-analytics-webpack-plugin": "^0.1.17",
     "type-fest": "^3.12.0",
-    "typescript": "^4.8.4",
+    "typescript": "^5.1.6",
     "wait-port": "^0.2.9",
     "webpack": "^5.76.0",
     "webpack-bundle-analyzer": "^4.5.0",
diff --git a/src/ONYXKEYS.js b/src/ONYXKEYS.js
deleted file mode 100755
index 27e7f9f0ecf3..000000000000
--- a/src/ONYXKEYS.js
+++ /dev/null
@@ -1,272 +0,0 @@
-/**
- * This is a file containing constants for all the top level keys in our store
- */
-export default {
-    // Holds information about the users account that is logging in
-    ACCOUNT: 'account',
-
-    // Holds the reportID for the report between the user and their account manager
-    ACCOUNT_MANAGER_REPORT_ID: 'accountManagerReportID',
-
-    // Boolean flag only true when first set
-    NVP_IS_FIRST_TIME_NEW_EXPENSIFY_USER: 'isFirstTimeNewExpensifyUser',
-
-    // Holds an array of client IDs which is used for multi-tabs on web in order to know
-    // which tab is the leader, and which ones are the followers
-    ACTIVE_CLIENTS: 'activeClients',
-
-    // A unique ID for the device
-    DEVICE_ID: 'deviceID',
-
-    // Boolean flag set whenever the sidebar has loaded
-    IS_SIDEBAR_LOADED: 'isSidebarLoaded',
-
-    // Note: These are Persisted Requests - not all requests in the main queue as the key name might lead one to believe
-    PERSISTED_REQUESTS: 'networkRequestQueue',
-
-    // Onyx updates from a response, or success or failure data from a request.
-    QUEUED_ONYX_UPDATES: 'queuedOnyxUpdates',
-
-    // Stores current date
-    CURRENT_DATE: 'currentDate',
-
-    // Credentials to authenticate the user
-    CREDENTIALS: 'credentials',
-
-    // Contains loading data for the IOU feature (MoneyRequestModal, IOUDetail, & MoneyRequestPreview Components)
-    IOU: 'iou',
-
-    // Keeps track if there is modal currently visible or not
-    MODAL: 'modal',
-
-    // Has information about the network status (offline/online)
-    NETWORK: 'network',
-
-    // draft status
-    CUSTOM_STATUS_DRAFT: 'customStatusDraft',
-
-    // Contains all the personalDetails the user has access to, keyed by accountID
-    PERSONAL_DETAILS_LIST: 'personalDetailsList',
-
-    // Contains all the private personal details of the user
-    PRIVATE_PERSONAL_DETAILS: 'private_personalDetails',
-
-    // Contains all the info for Tasks
-    TASK: 'task',
-
-    // Contains a list of all currencies available to the user - user can
-    // select a currency based on the list
-    CURRENCY_LIST: 'currencyList',
-
-    // Indicates whether an update is available and ready to be installed.
-    UPDATE_AVAILABLE: 'updateAvailable',
-
-    // Indicates that a request to join a screen share with a GuidesPlus agent was received
-    SCREEN_SHARE_REQUEST: 'screenShareRequest',
-
-    // Saves the current country code which is displayed when the user types a phone number without
-    // an international code
-    COUNTRY_CODE: 'countryCode',
-
-    // The 'country' field in this code represents the return country based on the user's IP address.
-    // It is expected to provide a two-letter country code such as US for United States, and so on.
-    COUNTRY: 'country',
-
-    // Contains all the users settings for the Settings page and sub pages
-    USER: 'user',
-
-    // Contains metadata (partner, login, validation date) for all of the user's logins
-    LOGIN_LIST: 'loginList',
-
-    // Information about the current session (authToken, accountID, email, loading, error)
-    SESSION: 'session',
-    BETAS: 'betas',
-
-    // NVP keys
-    // Contains the user's payPalMe data
-    PAYPAL: 'paypal',
-
-    // Contains the user preference for the LHN priority mode
-    NVP_PRIORITY_MODE: 'nvp_priorityMode',
-
-    // Contains the users's block expiration (if they have one)
-    NVP_BLOCKED_FROM_CONCIERGE: 'private_blockedFromConcierge',
-
-    // A unique identifier that each user has that's used to send notifications
-    NVP_PRIVATE_PUSH_NOTIFICATION_ID: 'private_pushNotificationID',
-
-    // The NVP with the last payment method used per policy
-    NVP_LAST_PAYMENT_METHOD: 'nvp_lastPaymentMethod',
-
-    // Does this user have push notifications enabled for this device?
-    PUSH_NOTIFICATIONS_ENABLED: 'pushNotificationsEnabled',
-
-    // Plaid data (access tokens, bank accounts ...)
-    PLAID_DATA: 'plaidData',
-
-    // If we disabled Plaid because of too many attempts
-    IS_PLAID_DISABLED: 'isPlaidDisabled',
-
-    // Token needed to initialize Plaid link
-    PLAID_LINK_TOKEN: 'plaidLinkToken',
-
-    // Token needed to initialize Onfido
-    ONFIDO_TOKEN: 'onfidoToken',
-
-    // Collection Keys
-    COLLECTION: {
-        DOWNLOAD: 'download_',
-        POLICY: 'policy_',
-        POLICY_MEMBERS: 'policyMembers_',
-        POLICY_CATEGORIES: 'policyCategories_',
-        WORKSPACE_INVITE_MEMBERS_DRAFT: 'workspaceInviteMembersDraft_',
-        REPORT: 'report_',
-        REPORT_ACTIONS: 'reportActions_',
-        REPORT_ACTIONS_DRAFTS: 'reportActionsDrafts_',
-        REPORT_ACTIONS_REACTIONS: 'reportActionsReactions_',
-        REPORT_DRAFT_COMMENT: 'reportDraftComment_',
-        REPORT_DRAFT_COMMENT_NUMBER_OF_LINES: 'reportDraftCommentNumberOfLines_',
-        REPORT_IS_COMPOSER_FULL_SIZE: 'reportIsComposerFullSize_',
-        REPORT_USER_IS_TYPING: 'reportUserIsTyping_',
-        SECURITY_GROUP: 'securityGroup_',
-        TRANSACTION: 'transactions_',
-
-        // This is deprecated, but needed for a migration, so we still need to include it here so that it will be initialized in Onyx.init
-        DEPRECATED_POLICY_MEMBER_LIST: 'policyMemberList_',
-    },
-
-    // Indicates which locale should be used
-    NVP_PREFERRED_LOCALE: 'preferredLocale',
-
-    // List of transactionIDs in process of rejection
-    TRANSACTIONS_BEING_REJECTED: 'transactionsBeingRejected',
-
-    // User's Expensify Wallet
-    USER_WALLET: 'userWallet',
-
-    // Object containing Onfido SDK Token + applicantID
-    WALLET_ONFIDO: 'walletOnfido',
-
-    // Stores information about additional details form entry
-    WALLET_ADDITIONAL_DETAILS: 'walletAdditionalDetails',
-
-    // Object containing Wallet terms step state
-    WALLET_TERMS: 'walletTerms',
-
-    // The user's bank accounts
-    BANK_ACCOUNT_LIST: 'bankAccountList',
-
-    // The user's credit cards
-    FUND_LIST: 'fundList',
-
-    // The user's Expensify cards
-    CORPORATE_CARD_LIST: 'corporateCardList',
-
-    // Stores information about the user's saved statements
-    WALLET_STATEMENT: 'walletStatement',
-
-    // Stores information about the active personal bank account being set up
-    PERSONAL_BANK_ACCOUNT: 'personalBankAccount',
-
-    // Stores information about the active reimbursement account being set up
-    REIMBURSEMENT_ACCOUNT: 'reimbursementAccount',
-
-    // Stores draft information about the active reimbursement account being set up
-    REIMBURSEMENT_ACCOUNT_DRAFT: 'reimbursementAccountDraft',
-
-    // Store preferred skintone for emoji
-    PREFERRED_EMOJI_SKIN_TONE: 'preferredEmojiSkinTone',
-
-    // Store frequently used emojis for this user
-    FREQUENTLY_USED_EMOJIS: 'frequentlyUsedEmojis',
-
-    // Stores Workspace ID that will be tied to reimbursement account during setup
-    REIMBURSEMENT_ACCOUNT_WORKSPACE_ID: 'reimbursementAccountWorkspaceID',
-
-    // Set when we are loading payment methods
-    IS_LOADING_PAYMENT_METHODS: 'isLoadingPaymentMethods',
-
-    // Is report data loading?
-    IS_LOADING_REPORT_DATA: 'isLoadingReportData',
-
-    // Is Keyboard shortcuts modal open?
-    IS_SHORTCUTS_MODAL_OPEN: 'isShortcutsModalOpen',
-
-    // Is the test tools modal open?
-    IS_TEST_TOOLS_MODAL_OPEN: 'isTestToolsModalOpen',
-
-    // Stores information about active wallet transfer amount, selectedAccountID, status, etc
-    WALLET_TRANSFER: 'walletTransfer',
-
-    // The policyID of the last workspace whose settings were accessed by the user
-    LAST_ACCESSED_WORKSPACE_POLICY_ID: 'lastAccessedWorkspacePolicyID',
-
-    // List of Form ids
-    FORMS: {
-        ADD_DEBIT_CARD_FORM: 'addDebitCardForm',
-        REIMBURSEMENT_ACCOUNT_FORM: 'reimbursementAccount',
-        WORKSPACE_SETTINGS_FORM: 'workspaceSettingsForm',
-        WORKSPACE_RATE_AND_UNIT_FORM: 'workspaceRateAndUnitForm',
-        CLOSE_ACCOUNT_FORM: 'closeAccount',
-        PROFILE_SETTINGS_FORM: 'profileSettingsForm',
-        DISPLAY_NAME_FORM: 'displayNameForm',
-        ROOM_NAME_FORM: 'roomNameForm',
-        WELCOME_MESSAGE_FORM: 'welcomeMessageForm',
-        LEGAL_NAME_FORM: 'legalNameForm',
-        WORKSPACE_INVITE_MESSAGE_FORM: 'workspaceInviteMessageForm',
-        DATE_OF_BIRTH_FORM: 'dateOfBirthForm',
-        HOME_ADDRESS_FORM: 'homeAddressForm',
-        NEW_ROOM_FORM: 'newRoomForm',
-        ROOM_SETTINGS_FORM: 'roomSettingsForm',
-        NEW_TASK_FORM: 'newTaskForm',
-        EDIT_TASK_FORM: 'editTaskForm',
-        MONEY_REQUEST_DESCRIPTION_FORM: 'moneyRequestDescriptionForm',
-        MONEY_REQUEST_MERCHANT_FORM: 'moneyRequestMerchantForm',
-        MONEY_REQUEST_AMOUNT_FORM: 'moneyRequestAmountForm',
-        MONEY_REQUEST_DATE_FORM: 'moneyRequestCreatedForm',
-        NEW_CONTACT_METHOD_FORM: 'newContactMethodForm',
-        PAYPAL_FORM: 'payPalForm',
-        WAYPOINT_FORM: 'waypointForm',
-        WAYPOINT_FORM_DRAFT: 'waypointFormDraft',
-        SETTINGS_STATUS_SET_FORM: 'settingsStatusSetForm',
-        SETTINGS_STATUS_CLEAR_AFTER_FORM: 'settingsStatusClearAfterForm',
-        SETTINGS_STATUS_SET_CLEAR_AFTER_FORM: 'settingsStatusSetClearAfterForm',
-    },
-
-    // Whether we should show the compose input or not
-    SHOULD_SHOW_COMPOSE_INPUT: 'shouldShowComposeInput',
-
-    // Is app in beta version
-    IS_BETA: 'isBeta',
-
-    // The theme setting set by the user in preferences.
-    // This can be either "light", "dark" or "system"
-    PREFERRED_THEME: 'preferredTheme',
-
-    // Whether we're checking if the room is public or not
-    IS_CHECKING_PUBLIC_ROOM: 'isCheckingPublicRoom',
-
-    // A map of the user's security group IDs they belong to in specific domains
-    MY_DOMAIN_SECURITY_GROUPS: 'myDomainSecurityGroups',
-
-    // Report ID of the last report the user viewed as anonymous user
-    LAST_OPENED_PUBLIC_ROOM_ID: 'lastOpenedPublicRoomID',
-
-    // Experimental memory only Onyx mode flag
-    IS_USING_MEMORY_ONLY_KEYS: 'isUsingMemoryOnlyKeys',
-
-    // Information about the onyx updates IDs that were received from the server
-    ONYX_UPDATES_FROM_SERVER: 'onyxUpdatesFromServer',
-
-    // The last update ID that was applied to the client
-    ONYX_UPDATES_LAST_UPDATE_ID_APPLIED_TO_CLIENT: 'OnyxUpdatesLastUpdateIDAppliedToClient',
-
-    // The access token to be used with the Mapbox library
-    MAPBOX_ACCESS_TOKEN: 'mapboxAccessToken',
-
-    // Manual request tab selector
-    SELECTED_TAB: 'selectedTab',
-
-    // Receipt upload modal
-    RECEIPT_MODAL: 'receiptModal',
-};
diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts
new file mode 100755
index 000000000000..3c0b3ee9a6d6
--- /dev/null
+++ b/src/ONYXKEYS.ts
@@ -0,0 +1,399 @@
+import {ValueOf} from 'type-fest';
+import DeepValueOf from './types/utils/DeepValueOf';
+import * as OnyxTypes from './types/onyx';
+import CONST from './CONST';
+
+/**
+ * This is a file containing constants for all the top level keys in our store
+ */
+const ONYXKEYS = {
+    /** Holds information about the users account that is logging in */
+    ACCOUNT: 'account',
+
+    /** Holds the reportID for the report between the user and their account manager */
+    ACCOUNT_MANAGER_REPORT_ID: 'accountManagerReportID',
+
+    /** Boolean flag only true when first set */
+    NVP_IS_FIRST_TIME_NEW_EXPENSIFY_USER: 'isFirstTimeNewExpensifyUser',
+
+    /** Holds an array of client IDs which is used for multi-tabs on web in order to know
+     * which tab is the leader, and which ones are the followers */
+    ACTIVE_CLIENTS: 'activeClients',
+
+    /** A unique ID for the device */
+    DEVICE_ID: 'deviceID',
+
+    /** Boolean flag set whenever the sidebar has loaded */
+    IS_SIDEBAR_LOADED: 'isSidebarLoaded',
+
+    /** Note: These are Persisted Requests - not all requests in the main queue as the key name might lead one to believe */
+    PERSISTED_REQUESTS: 'networkRequestQueue',
+
+    /** Onyx updates from a response, or success or failure data from a request. */
+    QUEUED_ONYX_UPDATES: 'queuedOnyxUpdates',
+
+    /** Stores current date */
+    CURRENT_DATE: 'currentDate',
+
+    /** Credentials to authenticate the user */
+    CREDENTIALS: 'credentials',
+
+    // Contains loading data for the IOU feature (MoneyRequestModal, IOUDetail, & MoneyRequestPreview Components)
+    IOU: 'iou',
+
+    /** Keeps track if there is modal currently visible or not */
+    MODAL: 'modal',
+
+    /** Has information about the network status (offline/online) */
+    NETWORK: 'network',
+
+    // draft status
+    CUSTOM_STATUS_DRAFT: 'customStatusDraft',
+
+    /** Contains all the personalDetails the user has access to, keyed by accountID */
+    PERSONAL_DETAILS_LIST: 'personalDetailsList',
+
+    /** Contains all the private personal details of the user */
+    PRIVATE_PERSONAL_DETAILS: 'private_personalDetails',
+
+    /** Contains all the info for Tasks */
+    TASK: 'task',
+
+    /** Contains a list of all currencies available to the user - user can
+     * select a currency based on the list */
+    CURRENCY_LIST: 'currencyList',
+
+    /** Indicates whether an update is available and ready to be installed. */
+    UPDATE_AVAILABLE: 'updateAvailable',
+
+    /** Indicates that a request to join a screen share with a GuidesPlus agent was received */
+    SCREEN_SHARE_REQUEST: 'screenShareRequest',
+
+    /** Saves the current country code which is displayed when the user types a phone number without
+     *  an international code */
+    COUNTRY_CODE: 'countryCode',
+
+    /**  The 'country' field in this code represents the return country based on the user's IP address.
+     * It is expected to provide a two-letter country code such as US for United States, and so on. */
+    COUNTRY: 'country',
+
+    /** Contains all the users settings for the Settings page and sub pages */
+    USER: 'user',
+
+    /** Contains metadata (partner, login, validation date) for all of the user's logins */
+    LOGIN_LIST: 'loginList',
+
+    /** Information about the current session (authToken, accountID, email, loading, error) */
+    SESSION: 'session',
+    BETAS: 'betas',
+
+    /** NVP keys
+     * Contains the user's payPalMe data */
+    PAYPAL: 'paypal',
+
+    /** Contains the user preference for the LHN priority mode */
+    NVP_PRIORITY_MODE: 'nvp_priorityMode',
+
+    /** Contains the users's block expiration (if they have one) */
+    NVP_BLOCKED_FROM_CONCIERGE: 'private_blockedFromConcierge',
+
+    /** A unique identifier that each user has that's used to send notifications */
+    NVP_PRIVATE_PUSH_NOTIFICATION_ID: 'private_pushNotificationID',
+
+    /** The NVP with the last payment method used per policy */
+    NVP_LAST_PAYMENT_METHOD: 'nvp_lastPaymentMethod',
+
+    /** Does this user have push notifications enabled for this device? */
+    PUSH_NOTIFICATIONS_ENABLED: 'pushNotificationsEnabled',
+
+    /** Plaid data (access tokens, bank accounts ...) */
+    PLAID_DATA: 'plaidData',
+
+    /** If we disabled Plaid because of too many attempts */
+    IS_PLAID_DISABLED: 'isPlaidDisabled',
+
+    /** Token needed to initialize Plaid link */
+    PLAID_LINK_TOKEN: 'plaidLinkToken',
+
+    /** Token needed to initialize Onfido */
+    ONFIDO_TOKEN: 'onfidoToken',
+
+    /** Indicates which locale should be used */
+    NVP_PREFERRED_LOCALE: 'preferredLocale',
+
+    /** User's Expensify Wallet */
+    USER_WALLET: 'userWallet',
+
+    /** Object containing Onfido SDK Token + applicantID */
+    WALLET_ONFIDO: 'walletOnfido',
+
+    /** Stores information about additional details form entry */
+    WALLET_ADDITIONAL_DETAILS: 'walletAdditionalDetails',
+
+    /** Object containing Wallet terms step state */
+    WALLET_TERMS: 'walletTerms',
+
+    /** The user's bank accounts */
+    BANK_ACCOUNT_LIST: 'bankAccountList',
+
+    /** The user's credit cards (renamed from cardList) */
+    FUND_LIST: 'fundList',
+
+    // The user's Expensify cards
+    CORPORATE_CARD_LIST: 'corporateCardList',
+
+    /** Stores information about the user's saved statements */
+    WALLET_STATEMENT: 'walletStatement',
+
+    /** Stores information about the active personal bank account being set up */
+    PERSONAL_BANK_ACCOUNT: 'personalBankAccount',
+
+    /** Stores information about the active reimbursement account being set up */
+    REIMBURSEMENT_ACCOUNT: 'reimbursementAccount',
+
+    /** Stores draft information about the active reimbursement account being set up */
+    REIMBURSEMENT_ACCOUNT_DRAFT: 'reimbursementAccountDraft',
+
+    /** Store preferred skintone for emoji */
+    PREFERRED_EMOJI_SKIN_TONE: 'preferredEmojiSkinTone',
+
+    /** Store frequently used emojis for this user */
+    FREQUENTLY_USED_EMOJIS: 'frequentlyUsedEmojis',
+
+    /** Stores Workspace ID that will be tied to reimbursement account during setup */
+    REIMBURSEMENT_ACCOUNT_WORKSPACE_ID: 'reimbursementAccountWorkspaceID',
+
+    /** Set when we are loading payment methods */
+    IS_LOADING_PAYMENT_METHODS: 'isLoadingPaymentMethods',
+
+    /** Is report data loading? */
+    IS_LOADING_REPORT_DATA: 'isLoadingReportData',
+
+    /** Is Keyboard shortcuts modal open? */
+    IS_SHORTCUTS_MODAL_OPEN: 'isShortcutsModalOpen',
+
+    /** Is the test tools modal open? */
+    IS_TEST_TOOLS_MODAL_OPEN: 'isTestToolsModalOpen',
+
+    /** Stores information about active wallet transfer amount, selectedAccountID, status, etc */
+    WALLET_TRANSFER: 'walletTransfer',
+
+    /** The policyID of the last workspace whose settings were accessed by the user */
+    LAST_ACCESSED_WORKSPACE_POLICY_ID: 'lastAccessedWorkspacePolicyID',
+
+    /** Whether we should show the compose input or not */
+    SHOULD_SHOW_COMPOSE_INPUT: 'shouldShowComposeInput',
+
+    /** Is app in beta version */
+    IS_BETA: 'isBeta',
+
+    /** Whether we're checking if the room is public or not */
+    IS_CHECKING_PUBLIC_ROOM: 'isCheckingPublicRoom',
+
+    /** A map of the user's security group IDs they belong to in specific domains */
+    MY_DOMAIN_SECURITY_GROUPS: 'myDomainSecurityGroups',
+
+    /** Report ID of the last report the user viewed as anonymous user */
+    LAST_OPENED_PUBLIC_ROOM_ID: 'lastOpenedPublicRoomID',
+
+    // The theme setting set by the user in preferences.
+    // This can be either "light", "dark" or "system"
+    PREFERRED_THEME: 'preferredTheme',
+
+    // Experimental memory only Onyx mode flag
+    IS_USING_MEMORY_ONLY_KEYS: 'isUsingMemoryOnlyKeys',
+
+    // Information about the onyx updates IDs that were received from the server
+    ONYX_UPDATES_FROM_SERVER: 'onyxUpdatesFromServer',
+
+    // The last update ID that was applied to the client
+    ONYX_UPDATES_LAST_UPDATE_ID_APPLIED_TO_CLIENT: 'OnyxUpdatesLastUpdateIDAppliedToClient',
+
+    // Manual request tab selector
+    SELECTED_TAB: 'selectedTab',
+
+    // Receipt upload modal
+    RECEIPT_MODAL: 'receiptModal',
+
+    // The access token to be used with the Mapbox library
+    MAPBOX_ACCESS_TOKEN: 'mapboxAccessToken',
+
+    /** Collection Keys */
+    COLLECTION: {
+        DOWNLOAD: 'download_',
+        POLICY: 'policy_',
+        POLICY_MEMBERS: 'policyMembers_',
+        POLICY_CATEGORIES: 'policyCategories_',
+        WORKSPACE_INVITE_MEMBERS_DRAFT: 'workspaceInviteMembersDraft_',
+        REPORT: 'report_',
+        REPORT_ACTIONS: 'reportActions_',
+        REPORT_ACTIONS_DRAFTS: 'reportActionsDrafts_',
+        REPORT_ACTIONS_REACTIONS: 'reportActionsReactions_',
+        REPORT_DRAFT_COMMENT: 'reportDraftComment_',
+        REPORT_DRAFT_COMMENT_NUMBER_OF_LINES: 'reportDraftCommentNumberOfLines_',
+        REPORT_IS_COMPOSER_FULL_SIZE: 'reportIsComposerFullSize_',
+        REPORT_USER_IS_TYPING: 'reportUserIsTyping_',
+        SECURITY_GROUP: 'securityGroup_',
+        TRANSACTION: 'transactions_',
+
+        /** This is deprecated, but needed for a migration, so we still need to include it here so that it will be initialized in Onyx.init */
+        DEPRECATED_POLICY_MEMBER_LIST: 'policyMemberList_',
+    },
+
+    /** List of Form ids */
+    FORMS: {
+        ADD_DEBIT_CARD_FORM: 'addDebitCardForm',
+        WORKSPACE_SETTINGS_FORM: 'workspaceSettingsForm',
+        WORKSPACE_RATE_AND_UNIT_FORM: 'workspaceRateAndUnitForm',
+        CLOSE_ACCOUNT_FORM: 'closeAccount',
+        PROFILE_SETTINGS_FORM: 'profileSettingsForm',
+        DISPLAY_NAME_FORM: 'displayNameForm',
+        ROOM_NAME_FORM: 'roomNameForm',
+        WELCOME_MESSAGE_FORM: 'welcomeMessageForm',
+        LEGAL_NAME_FORM: 'legalNameForm',
+        WORKSPACE_INVITE_MESSAGE_FORM: 'workspaceInviteMessageForm',
+        DATE_OF_BIRTH_FORM: 'dateOfBirthForm',
+        HOME_ADDRESS_FORM: 'homeAddressForm',
+        NEW_ROOM_FORM: 'newRoomForm',
+        ROOM_SETTINGS_FORM: 'roomSettingsForm',
+        NEW_TASK_FORM: 'newTaskForm',
+        EDIT_TASK_FORM: 'editTaskForm',
+        MONEY_REQUEST_DESCRIPTION_FORM: 'moneyRequestDescriptionForm',
+        MONEY_REQUEST_MERCHANT_FORM: 'moneyRequestMerchantForm',
+        MONEY_REQUEST_AMOUNT_FORM: 'moneyRequestAmountForm',
+        MONEY_REQUEST_DATE_FORM: 'moneyRequestCreatedForm',
+        NEW_CONTACT_METHOD_FORM: 'newContactMethodForm',
+        PAYPAL_FORM: 'payPalForm',
+        WAYPOINT_FORM: 'waypointForm',
+        WAYPOINT_FORM_DRAFT: 'waypointFormDraft',
+        SETTINGS_STATUS_SET_FORM: 'settingsStatusSetForm',
+        SETTINGS_STATUS_CLEAR_AFTER_FORM: 'settingsStatusClearAfterForm',
+        SETTINGS_STATUS_SET_CLEAR_AFTER_FORM: 'settingsStatusSetClearAfterForm',
+    },
+} as const;
+
+type OnyxKeysMap = typeof ONYXKEYS;
+type OnyxCollectionKey = ValueOf<OnyxKeysMap['COLLECTION']>;
+type OnyxKey = DeepValueOf<Omit<OnyxKeysMap, 'COLLECTION'>>;
+
+type OnyxValues = {
+    [ONYXKEYS.ACCOUNT]: OnyxTypes.Account;
+    [ONYXKEYS.ACCOUNT_MANAGER_REPORT_ID]: string;
+    [ONYXKEYS.NVP_IS_FIRST_TIME_NEW_EXPENSIFY_USER]: boolean;
+    [ONYXKEYS.ACTIVE_CLIENTS]: string[];
+    [ONYXKEYS.DEVICE_ID]: string;
+    [ONYXKEYS.IS_SIDEBAR_LOADED]: boolean;
+    [ONYXKEYS.PERSISTED_REQUESTS]: OnyxTypes.Request[];
+    [ONYXKEYS.QUEUED_ONYX_UPDATES]: OnyxTypes.QueuedOnyxUpdates;
+    [ONYXKEYS.CURRENT_DATE]: string;
+    [ONYXKEYS.CREDENTIALS]: OnyxTypes.Credentials;
+    [ONYXKEYS.IOU]: OnyxTypes.IOU;
+    [ONYXKEYS.MODAL]: OnyxTypes.Modal;
+    [ONYXKEYS.NETWORK]: OnyxTypes.Network;
+    [ONYXKEYS.CUSTOM_STATUS_DRAFT]: OnyxTypes.CustomStatusDraft;
+    [ONYXKEYS.PERSONAL_DETAILS_LIST]: Record<string, OnyxTypes.PersonalDetails>;
+    [ONYXKEYS.PRIVATE_PERSONAL_DETAILS]: OnyxTypes.PrivatePersonalDetails;
+    [ONYXKEYS.TASK]: OnyxTypes.Task;
+    [ONYXKEYS.CURRENCY_LIST]: Record<string, OnyxTypes.Currency>;
+    [ONYXKEYS.UPDATE_AVAILABLE]: boolean;
+    [ONYXKEYS.SCREEN_SHARE_REQUEST]: OnyxTypes.ScreenShareRequest;
+    [ONYXKEYS.COUNTRY_CODE]: number;
+    [ONYXKEYS.COUNTRY]: string;
+    [ONYXKEYS.USER]: OnyxTypes.User;
+    [ONYXKEYS.LOGIN_LIST]: OnyxTypes.Login;
+    [ONYXKEYS.SESSION]: OnyxTypes.Session;
+    [ONYXKEYS.BETAS]: OnyxTypes.Beta[];
+    [ONYXKEYS.PAYPAL]: OnyxTypes.Paypal;
+    [ONYXKEYS.NVP_PRIORITY_MODE]: ValueOf<typeof CONST.PRIORITY_MODE>;
+    [ONYXKEYS.NVP_BLOCKED_FROM_CONCIERGE]: OnyxTypes.BlockedFromConcierge;
+    [ONYXKEYS.NVP_PRIVATE_PUSH_NOTIFICATION_ID]: string;
+    [ONYXKEYS.NVP_LAST_PAYMENT_METHOD]: Record<string, string>;
+    [ONYXKEYS.PUSH_NOTIFICATIONS_ENABLED]: boolean;
+    [ONYXKEYS.PLAID_DATA]: OnyxTypes.PlaidData;
+    [ONYXKEYS.IS_PLAID_DISABLED]: boolean;
+    [ONYXKEYS.PLAID_LINK_TOKEN]: string;
+    [ONYXKEYS.ONFIDO_TOKEN]: string;
+    [ONYXKEYS.NVP_PREFERRED_LOCALE]: ValueOf<typeof CONST.LOCALES>;
+    [ONYXKEYS.USER_WALLET]: OnyxTypes.UserWallet;
+    [ONYXKEYS.WALLET_ONFIDO]: OnyxTypes.WalletOnfido;
+    [ONYXKEYS.WALLET_ADDITIONAL_DETAILS]: OnyxTypes.WalletAdditionalDetails;
+    [ONYXKEYS.WALLET_TERMS]: OnyxTypes.WalletTerms;
+    [ONYXKEYS.BANK_ACCOUNT_LIST]: Record<string, OnyxTypes.BankAccount>;
+    [ONYXKEYS.FUND_LIST]: Record<string, OnyxTypes.Card>;
+    [ONYXKEYS.WALLET_STATEMENT]: OnyxTypes.WalletStatement;
+    [ONYXKEYS.PERSONAL_BANK_ACCOUNT]: OnyxTypes.PersonalBankAccount;
+    [ONYXKEYS.REIMBURSEMENT_ACCOUNT]: OnyxTypes.ReimbursementAccount;
+    [ONYXKEYS.REIMBURSEMENT_ACCOUNT_DRAFT]: OnyxTypes.ReimbursementAccountDraft;
+    [ONYXKEYS.PREFERRED_EMOJI_SKIN_TONE]: string | number;
+    [ONYXKEYS.FREQUENTLY_USED_EMOJIS]: OnyxTypes.FrequentlyUsedEmoji[];
+    [ONYXKEYS.REIMBURSEMENT_ACCOUNT_WORKSPACE_ID]: string;
+    [ONYXKEYS.IS_LOADING_PAYMENT_METHODS]: boolean;
+    [ONYXKEYS.IS_LOADING_REPORT_DATA]: boolean;
+    [ONYXKEYS.IS_SHORTCUTS_MODAL_OPEN]: boolean;
+    [ONYXKEYS.IS_TEST_TOOLS_MODAL_OPEN]: boolean;
+    [ONYXKEYS.WALLET_TRANSFER]: OnyxTypes.WalletTransfer;
+    [ONYXKEYS.LAST_ACCESSED_WORKSPACE_POLICY_ID]: string;
+    [ONYXKEYS.SHOULD_SHOW_COMPOSE_INPUT]: boolean;
+    [ONYXKEYS.IS_BETA]: boolean;
+    [ONYXKEYS.IS_CHECKING_PUBLIC_ROOM]: boolean;
+    [ONYXKEYS.MY_DOMAIN_SECURITY_GROUPS]: Record<string, string>;
+    [ONYXKEYS.LAST_OPENED_PUBLIC_ROOM_ID]: string;
+    [ONYXKEYS.PREFERRED_THEME]: ValueOf<typeof CONST.THEME>;
+    [ONYXKEYS.IS_USING_MEMORY_ONLY_KEYS]: boolean;
+    [ONYXKEYS.SELECTED_TAB]: string;
+    [ONYXKEYS.RECEIPT_MODAL]: OnyxTypes.ReceiptModal;
+    [ONYXKEYS.MAPBOX_ACCESS_TOKEN]: OnyxTypes.MapboxAccessToken;
+    [ONYXKEYS.ONYX_UPDATES_FROM_SERVER]: number;
+    [ONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID_APPLIED_TO_CLIENT]: number;
+
+    // Collections
+    [ONYXKEYS.COLLECTION.DOWNLOAD]: OnyxTypes.Download;
+    [ONYXKEYS.COLLECTION.POLICY]: OnyxTypes.Policy;
+    [ONYXKEYS.COLLECTION.POLICY_CATEGORIES]: unknown;
+    [ONYXKEYS.COLLECTION.POLICY_MEMBERS]: OnyxTypes.PolicyMember;
+    [ONYXKEYS.COLLECTION.DEPRECATED_POLICY_MEMBER_LIST]: OnyxTypes.PolicyMember;
+    [ONYXKEYS.COLLECTION.WORKSPACE_INVITE_MEMBERS_DRAFT]: Record<string, number>;
+    [ONYXKEYS.COLLECTION.REPORT]: OnyxTypes.Report;
+    [ONYXKEYS.COLLECTION.REPORT_ACTIONS]: OnyxTypes.ReportAction;
+    [ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS]: string;
+    [ONYXKEYS.COLLECTION.REPORT_ACTIONS_REACTIONS]: OnyxTypes.ReportActionReactions;
+    [ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT]: string;
+    [ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT_NUMBER_OF_LINES]: number;
+    [ONYXKEYS.COLLECTION.REPORT_IS_COMPOSER_FULL_SIZE]: boolean;
+    [ONYXKEYS.COLLECTION.REPORT_USER_IS_TYPING]: boolean;
+    [ONYXKEYS.COLLECTION.SECURITY_GROUP]: OnyxTypes.SecurityGroup;
+    [ONYXKEYS.COLLECTION.TRANSACTION]: OnyxTypes.Transaction;
+
+    // Forms
+    [ONYXKEYS.FORMS.ADD_DEBIT_CARD_FORM]: OnyxTypes.AddDebitCardForm;
+    [ONYXKEYS.FORMS.WORKSPACE_SETTINGS_FORM]: OnyxTypes.Form;
+    [ONYXKEYS.FORMS.WORKSPACE_RATE_AND_UNIT_FORM]: OnyxTypes.Form;
+    [ONYXKEYS.FORMS.CLOSE_ACCOUNT_FORM]: OnyxTypes.Form;
+    [ONYXKEYS.FORMS.PROFILE_SETTINGS_FORM]: OnyxTypes.Form;
+    [ONYXKEYS.FORMS.DISPLAY_NAME_FORM]: OnyxTypes.Form;
+    [ONYXKEYS.FORMS.ROOM_NAME_FORM]: OnyxTypes.Form;
+    [ONYXKEYS.FORMS.WELCOME_MESSAGE_FORM]: OnyxTypes.Form;
+    [ONYXKEYS.FORMS.LEGAL_NAME_FORM]: OnyxTypes.Form;
+    [ONYXKEYS.FORMS.WORKSPACE_INVITE_MESSAGE_FORM]: OnyxTypes.Form;
+    [ONYXKEYS.FORMS.DATE_OF_BIRTH_FORM]: OnyxTypes.Form;
+    [ONYXKEYS.FORMS.HOME_ADDRESS_FORM]: OnyxTypes.Form;
+    [ONYXKEYS.FORMS.NEW_ROOM_FORM]: OnyxTypes.Form;
+    [ONYXKEYS.FORMS.ROOM_SETTINGS_FORM]: OnyxTypes.Form;
+    [ONYXKEYS.FORMS.NEW_TASK_FORM]: OnyxTypes.Form;
+    [ONYXKEYS.FORMS.EDIT_TASK_FORM]: OnyxTypes.Form;
+    [ONYXKEYS.FORMS.MONEY_REQUEST_DESCRIPTION_FORM]: OnyxTypes.Form;
+    [ONYXKEYS.FORMS.MONEY_REQUEST_MERCHANT_FORM]: OnyxTypes.Form;
+    [ONYXKEYS.FORMS.MONEY_REQUEST_AMOUNT_FORM]: OnyxTypes.Form;
+    [ONYXKEYS.FORMS.MONEY_REQUEST_DATE_FORM]: OnyxTypes.Form;
+    [ONYXKEYS.FORMS.MONEY_REQUEST_DATE_FORM]: OnyxTypes.Form;
+    [ONYXKEYS.FORMS.NEW_CONTACT_METHOD_FORM]: OnyxTypes.Form;
+    [ONYXKEYS.FORMS.PAYPAL_FORM]: OnyxTypes.Form;
+    [ONYXKEYS.FORMS.WAYPOINT_FORM]: OnyxTypes.Form;
+    [ONYXKEYS.FORMS.WAYPOINT_FORM_DRAFT]: OnyxTypes.Form;
+    [ONYXKEYS.FORMS.SETTINGS_STATUS_SET_FORM]: OnyxTypes.Form;
+    [ONYXKEYS.FORMS.SETTINGS_STATUS_CLEAR_AFTER_FORM]: OnyxTypes.Form;
+    [ONYXKEYS.FORMS.SETTINGS_STATUS_SET_CLEAR_AFTER_FORM]: OnyxTypes.Form;
+};
+
+export default ONYXKEYS;
+export type {OnyxKey, OnyxCollectionKey, OnyxValues};
diff --git a/src/global.d.ts b/src/global.d.ts
index 0e32eb6f7457..0dc745d5e0ea 100644
--- a/src/global.d.ts
+++ b/src/global.d.ts
@@ -1,3 +1,5 @@
+import {OnyxKey, OnyxCollectionKey, OnyxValues} from './ONYXKEYS';
+
 declare module '*.png' {
     const value: import('react-native').ImageSourcePropType;
     export default value;
@@ -15,3 +17,12 @@ declare module '*.svg' {
 }
 
 declare module 'react-native-device-info/jest/react-native-device-info-mock';
+
+declare module 'react-native-onyx' {
+    // eslint-disable-next-line @typescript-eslint/consistent-type-definitions
+    interface CustomTypeOptions {
+        keys: OnyxKey;
+        collectionKeys: OnyxCollectionKey;
+        values: OnyxValues;
+    }
+}
diff --git a/src/pages/ReimbursementAccount/ACHContractStep.js b/src/pages/ReimbursementAccount/ACHContractStep.js
index 6083661b0d0d..1ef43843571c 100644
--- a/src/pages/ReimbursementAccount/ACHContractStep.js
+++ b/src/pages/ReimbursementAccount/ACHContractStep.js
@@ -154,7 +154,7 @@ function ACHContractStep(props) {
                 guidesCallTaskID={CONST.GUIDES_CALL_TASK_IDS.WORKSPACE_BANK_ACCOUNT}
             />
             <Form
-                formID={ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM}
+                formID={ONYXKEYS.REIMBURSEMENT_ACCOUNT}
                 validate={validate}
                 onSubmit={submit}
                 submitButtonText={props.translate('common.saveAndContinue')}
diff --git a/src/pages/ReimbursementAccount/BankAccountManualStep.js b/src/pages/ReimbursementAccount/BankAccountManualStep.js
index e9e7c9436eef..2416639719fc 100644
--- a/src/pages/ReimbursementAccount/BankAccountManualStep.js
+++ b/src/pages/ReimbursementAccount/BankAccountManualStep.js
@@ -82,7 +82,7 @@ function BankAccountManualStep(props) {
                 onBackButtonPress={props.onBackButtonPress}
             />
             <Form
-                formID={ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM}
+                formID={ONYXKEYS.REIMBURSEMENT_ACCOUNT}
                 onSubmit={submit}
                 validate={validate}
                 submitButtonText={translate('common.continue')}
diff --git a/src/pages/ReimbursementAccount/BankAccountPlaidStep.js b/src/pages/ReimbursementAccount/BankAccountPlaidStep.js
index 4ebe77bf2440..1168a3ed271d 100644
--- a/src/pages/ReimbursementAccount/BankAccountPlaidStep.js
+++ b/src/pages/ReimbursementAccount/BankAccountPlaidStep.js
@@ -88,7 +88,7 @@ function BankAccountPlaidStep(props) {
                 onBackButtonPress={onBackButtonPress}
             />
             <Form
-                formID={ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM}
+                formID={ONYXKEYS.REIMBURSEMENT_ACCOUNT}
                 validate={validate}
                 onSubmit={submit}
                 scrollContextEnabled
diff --git a/src/pages/ReimbursementAccount/CompanyStep.js b/src/pages/ReimbursementAccount/CompanyStep.js
index 3a963bc61295..ca030901408d 100644
--- a/src/pages/ReimbursementAccount/CompanyStep.js
+++ b/src/pages/ReimbursementAccount/CompanyStep.js
@@ -159,7 +159,7 @@ class CompanyStep extends React.Component {
                     onBackButtonPress={this.props.onBackButtonPress}
                 />
                 <Form
-                    formID={ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM}
+                    formID={ONYXKEYS.REIMBURSEMENT_ACCOUNT}
                     validate={this.validate}
                     onSubmit={this.submit}
                     scrollContextEnabled
diff --git a/src/pages/ReimbursementAccount/RequestorStep.js b/src/pages/ReimbursementAccount/RequestorStep.js
index 5fd962be3b0d..9831f4b8190c 100644
--- a/src/pages/ReimbursementAccount/RequestorStep.js
+++ b/src/pages/ReimbursementAccount/RequestorStep.js
@@ -99,7 +99,7 @@ class RequestorStep extends React.Component {
                     onBackButtonPress={this.props.onBackButtonPress}
                 />
                 <Form
-                    formID={ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM}
+                    formID={ONYXKEYS.REIMBURSEMENT_ACCOUNT}
                     submitButtonText={this.props.translate('common.saveAndContinue')}
                     validate={this.validate}
                     scrollContextEnabled
diff --git a/src/setup/platformSetup/index.native.js b/src/setup/platformSetup/index.native.js
index d164600c7706..470bef78848f 100644
--- a/src/setup/platformSetup/index.native.js
+++ b/src/setup/platformSetup/index.native.js
@@ -21,10 +21,5 @@ export default function () {
     PushNotification.init();
     subscribeToReportCommentPushNotifications();
 
-    // Setup Flipper plugins when on dev
-    if (__DEV__ && typeof jest === 'undefined') {
-        require('flipper-plugin-bridgespy-client');
-    }
-
     Performance.setupPerformanceObserver();
 }
diff --git a/src/types/onyx/Account.ts b/src/types/onyx/Account.ts
new file mode 100644
index 000000000000..29f21d703466
--- /dev/null
+++ b/src/types/onyx/Account.ts
@@ -0,0 +1,52 @@
+import {ValueOf} from 'type-fest';
+import CONST from '../../CONST';
+import * as OnyxCommon from './OnyxCommon';
+
+type Account = {
+    /** URL to the assigned guide's appointment booking calendar */
+    guideCalendarLink?: string;
+
+    /** User recovery codes for setting up 2-FA */
+    recoveryCodes?: string;
+
+    /** Secret key to enable 2FA within the authenticator app */
+    twoFactorAuthSecretKey?: string;
+
+    /** Whether this account has 2FA enabled or not */
+    requiresTwoFactorAuth?: boolean;
+
+    /** Whether the account is validated */
+    validated?: boolean;
+
+    /** The primaryLogin associated with the account */
+    primaryLogin?: string;
+
+    /** The message to be displayed when code requested */
+    message?: string;
+
+    /** Accounts that are on a domain with an Approved Accountant */
+    doesDomainHaveApprovedAccountant?: boolean;
+
+    /** Form that is being loaded */
+    loadingForm?: ValueOf<typeof CONST.FORMS>;
+
+    /** Whether the user forgot their password */
+    forgotPassword?: boolean;
+
+    /** Whether the account exists */
+    accountExists?: boolean;
+
+    /** Is the account / domain under domain control? */
+    domainControlled?: boolean;
+
+    /** Whether the validation code has expired */
+    validateCodeExpired?: boolean;
+
+    /** Whether a sign is loading */
+    isLoading?: boolean;
+
+    errors?: OnyxCommon.Errors;
+    success?: string;
+};
+
+export default Account;
diff --git a/src/types/onyx/BankAccount.ts b/src/types/onyx/BankAccount.ts
new file mode 100644
index 000000000000..ccaaa7ebab78
--- /dev/null
+++ b/src/types/onyx/BankAccount.ts
@@ -0,0 +1,72 @@
+type AdditionalData = {
+    isP2PDebitCard?: boolean;
+    beneficialOwners?: string[];
+    currency?: string;
+    bankName?: string;
+    fieldsType?: string;
+    country?: string;
+};
+
+type AccountData = {
+    /** The masked bank account number */
+    accountNumber?: string;
+
+    /** The name of the institution (bank of america, etc */
+    addressName?: string;
+
+    /** Can we use this account to pay other people? */
+    allowDebit?: boolean;
+
+    /** Can we use this account to receive money from other people? */
+    defaultCredit?: boolean;
+
+    /** Is a saving account */
+    isSavings?: boolean;
+
+    /** Return whether or not this bank account has been risk checked */
+    riskChecked?: boolean;
+
+    /** Account routing number */
+    routingNumber?: string;
+
+    /** The status of the bank account */
+    state?: string;
+
+    /** All user emails that have access to this bank account */
+    sharees?: string[];
+
+    processor?: string;
+
+    /** The bankAccountID in the bankAccounts db */
+    bankAccountID?: number;
+
+    /** All data related to the bank account */
+    additionalData?: AdditionalData;
+
+    /** The bank account type */
+    type?: string;
+};
+
+type BankAccount = {
+    /** The bank account type */
+    accountType?: string;
+
+    /** string like 'Account ending in XXXX' */
+    description?: string;
+
+    isDefault?: boolean;
+
+    /** string like 'bankAccount-{<bankAccountID>}' where <bankAccountID> is the bankAccountID */
+    key?: string;
+
+    /** Alias for bankAccountID */
+    methodID?: number;
+
+    /** Alias for addressName */
+    title?: string;
+
+    /** All data related to the bank account */
+    accountData?: AccountData;
+};
+
+export default BankAccount;
diff --git a/src/types/onyx/Beta.ts b/src/types/onyx/Beta.ts
new file mode 100644
index 000000000000..d40d05a9ed3d
--- /dev/null
+++ b/src/types/onyx/Beta.ts
@@ -0,0 +1,6 @@
+import {ValueOf} from 'type-fest';
+import CONST from '../../CONST';
+
+type Beta = ValueOf<typeof CONST.BETAS>;
+
+export default Beta;
diff --git a/src/types/onyx/BlockedFromConcierge.ts b/src/types/onyx/BlockedFromConcierge.ts
new file mode 100644
index 000000000000..4eebd537604c
--- /dev/null
+++ b/src/types/onyx/BlockedFromConcierge.ts
@@ -0,0 +1,9 @@
+type BlockedFromConcierge = {
+    /** The date that the user will be unblocked */
+    expiresAt: string;
+
+    /** Number of times the user has been blocked. */
+    count: 1 | 2 | 3;
+};
+
+export default BlockedFromConcierge;
diff --git a/src/types/onyx/Card.ts b/src/types/onyx/Card.ts
new file mode 100644
index 000000000000..71ef3d4d98e7
--- /dev/null
+++ b/src/types/onyx/Card.ts
@@ -0,0 +1,32 @@
+type AdditionalData = {
+    isBillingCard?: boolean;
+    isP2PDebitCard?: boolean;
+};
+
+type AccountData = {
+    additionalData?: AdditionalData;
+    addressName?: string;
+    addressState?: string;
+    addressStreet?: string;
+    addressZip?: number;
+    cardMonth?: number;
+
+    /** The masked credit card number */
+    cardNumber?: string;
+
+    cardYear?: number;
+    created?: string;
+    currency?: string;
+    fundID?: number;
+};
+
+type Card = {
+    accountData?: AccountData;
+    accountType?: string;
+    description?: string;
+    key?: string;
+    methodID?: number;
+    title?: string;
+};
+
+export default Card;
diff --git a/src/types/onyx/Credentials.ts b/src/types/onyx/Credentials.ts
new file mode 100644
index 000000000000..f6a9ce669ad0
--- /dev/null
+++ b/src/types/onyx/Credentials.ts
@@ -0,0 +1,15 @@
+type Credentials = {
+    /** The email/phone the user logged in with */
+    login?: string;
+    password?: string;
+    twoFactorAuthCode?: string;
+
+    /** The validate code */
+    validateCode?: string;
+
+    autoGeneratedLogin?: string;
+    autoGeneratedPassword?: string;
+    accountID?: number;
+};
+
+export default Credentials;
diff --git a/src/types/onyx/Currency.ts b/src/types/onyx/Currency.ts
new file mode 100644
index 000000000000..770fcc33a9a9
--- /dev/null
+++ b/src/types/onyx/Currency.ts
@@ -0,0 +1,15 @@
+type Currency = {
+    /** Symbol for the currency */
+    symbol: string;
+
+    /** Name of the currency */
+    name: string;
+
+    /** ISO4217 Code for the currency */
+    ISO4217: string;
+
+    /** Number of decimals the currency can have, if this is missing, we assume it has 2 decimals */
+    decimals?: number;
+};
+
+export default Currency;
diff --git a/src/types/onyx/CustomStatusDraft.ts b/src/types/onyx/CustomStatusDraft.ts
new file mode 100644
index 000000000000..b2801a1d89e0
--- /dev/null
+++ b/src/types/onyx/CustomStatusDraft.ts
@@ -0,0 +1,12 @@
+type CustomStatusDraft = {
+    /** The emoji code of the draft status */
+    emojiCode: string;
+
+    /** The text of the draft status */
+    text: string;
+
+    /** ISO 8601 format string, which represents the time when the status should be cleared */
+    clearAfter: string;
+};
+
+export default CustomStatusDraft;
diff --git a/src/types/onyx/Download.ts b/src/types/onyx/Download.ts
new file mode 100644
index 000000000000..9c6c2f61f716
--- /dev/null
+++ b/src/types/onyx/Download.ts
@@ -0,0 +1,6 @@
+type Download = {
+    /** If a file download is happening */
+    isDownloading: boolean;
+};
+
+export default Download;
diff --git a/src/types/onyx/Form.ts b/src/types/onyx/Form.ts
new file mode 100644
index 000000000000..cda8c3c1017e
--- /dev/null
+++ b/src/types/onyx/Form.ts
@@ -0,0 +1,21 @@
+import * as OnyxCommon from './OnyxCommon';
+
+type Form = {
+    /** Controls the loading state of the form */
+    isLoading?: boolean;
+
+    /** Server side errors keyed by microtime */
+    errors?: OnyxCommon.Errors;
+
+    /** Field-specific server side errors keyed by microtime */
+    errorFields?: OnyxCommon.ErrorFields;
+};
+
+type AddDebitCardForm = Form & {
+    /** Whether or not the form has been submitted */
+    setupComplete: boolean;
+};
+
+export default Form;
+
+export type {AddDebitCardForm};
diff --git a/src/types/onyx/FrequentlyUsedEmoji.ts b/src/types/onyx/FrequentlyUsedEmoji.ts
new file mode 100644
index 000000000000..2276095df9b5
--- /dev/null
+++ b/src/types/onyx/FrequentlyUsedEmoji.ts
@@ -0,0 +1,18 @@
+type FrequentlyUsedEmoji = {
+    /** The emoji code */
+    code: string;
+
+    /** The name of the emoji */
+    name: string;
+
+    /** The number of times the emoji has been used */
+    count: number;
+
+    /** The timestamp in UNIX format when the emoji was last used */
+    lastUpdatedAt: number;
+
+    /** The emoji skin tone type */
+    types?: string[];
+};
+
+export default FrequentlyUsedEmoji;
diff --git a/src/types/onyx/IOU.ts b/src/types/onyx/IOU.ts
new file mode 100644
index 000000000000..373b5d990160
--- /dev/null
+++ b/src/types/onyx/IOU.ts
@@ -0,0 +1,19 @@
+type Participant = {
+    accountID: number;
+    login?: string;
+    isPolicyExpenseChat?: boolean;
+    isOwnPolicyExpenseChat?: boolean;
+    selected?: boolean;
+    reportID?: string;
+};
+
+type IOU = {
+    id: string;
+    amount?: number;
+    /** Selected Currency Code of the current IOU */
+    currency?: string;
+    comment?: string;
+    participants?: Participant[];
+};
+
+export default IOU;
diff --git a/src/types/onyx/Login.ts b/src/types/onyx/Login.ts
new file mode 100644
index 000000000000..60ea5985315e
--- /dev/null
+++ b/src/types/onyx/Login.ts
@@ -0,0 +1,20 @@
+import * as OnyxCommon from './OnyxCommon';
+
+type Login = {
+    /** Phone/Email associated with user */
+    partnerUserID?: string;
+
+    /** Value of partner name */
+    partnerName?: string;
+
+    /** Date login was validated, used to show info indicator status */
+    validatedDate?: string;
+
+    /** Field-specific server side errors keyed by microtime */
+    errorFields?: OnyxCommon.ErrorFields;
+
+    /** Field-specific pending states for offline UI status */
+    pendingFields?: OnyxCommon.ErrorFields;
+};
+
+export default Login;
diff --git a/src/types/onyx/MapboxAccessToken.ts b/src/types/onyx/MapboxAccessToken.ts
new file mode 100644
index 000000000000..bea23bcf86c4
--- /dev/null
+++ b/src/types/onyx/MapboxAccessToken.ts
@@ -0,0 +1,7 @@
+type MapboxAccessToken = {
+    token: string;
+    expiration: string;
+    errors: string[];
+};
+
+export default MapboxAccessToken;
diff --git a/src/types/onyx/Modal.ts b/src/types/onyx/Modal.ts
new file mode 100644
index 000000000000..126b56d4c504
--- /dev/null
+++ b/src/types/onyx/Modal.ts
@@ -0,0 +1,9 @@
+type Modal = {
+    /** Indicates when an Alert modal is about to be visible */
+    willAlertModalBecomeVisible?: boolean;
+
+    /** Indicates if there is a modal currently visible or not */
+    isVisible?: boolean;
+};
+
+export default Modal;
diff --git a/src/types/onyx/Network.ts b/src/types/onyx/Network.ts
new file mode 100644
index 000000000000..5af4c1170c3f
--- /dev/null
+++ b/src/types/onyx/Network.ts
@@ -0,0 +1,12 @@
+type Network = {
+    /** Is the network currently offline or not */
+    isOffline?: boolean;
+
+    /** Should the network be forced offline */
+    shouldForceOffline?: boolean;
+
+    /** Whether we should fail all network requests */
+    shouldFailAllRequests?: boolean;
+};
+
+export default Network;
diff --git a/src/types/onyx/OnyxCommon.ts b/src/types/onyx/OnyxCommon.ts
new file mode 100644
index 000000000000..36e9c6ae74ea
--- /dev/null
+++ b/src/types/onyx/OnyxCommon.ts
@@ -0,0 +1,17 @@
+import {ValueOf} from 'type-fest';
+import * as React from 'react';
+import CONST from '../../CONST';
+
+type PendingAction = ValueOf<typeof CONST.RED_BRICK_ROAD_PENDING_ACTION>;
+
+type ErrorFields = Record<string | number, Record<string, string>>;
+
+type Errors = Record<string, string>;
+
+type Icon = {
+    source: React.ReactNode | string;
+    type: 'avatar' | 'workspace';
+    name: string;
+};
+
+export type {Icon, PendingAction, ErrorFields, Errors};
diff --git a/src/types/onyx/OriginalMessage.ts b/src/types/onyx/OriginalMessage.ts
new file mode 100644
index 000000000000..d52489c36da9
--- /dev/null
+++ b/src/types/onyx/OriginalMessage.ts
@@ -0,0 +1,142 @@
+// TODO: Remove this after CONST.ts is migrated to TS
+/* eslint-disable @typescript-eslint/no-duplicate-type-constituents */
+import {ValueOf} from 'type-fest';
+import CONST from '../../CONST';
+
+type OriginalMessageIOU = {
+    actionName: typeof CONST.REPORT.ACTIONS.TYPE.IOU;
+    originalMessage: {
+        /** The ID of the iou transaction */
+        IOUTransactionID?: string;
+
+        IOUReportID?: number;
+        amount: number;
+        comment?: string;
+        currency: string;
+        lastModified?: string;
+        participantAccountIDs?: number[];
+        participants?: string[];
+        type: string;
+    };
+};
+
+type FlagSeverityName = 'spam' | 'inconsiderate' | 'bullying' | 'intimidation' | 'harassment' | 'assault';
+type FlagSeverity = {
+    accountID: number;
+    timestamp: string;
+};
+
+type Decision = {
+    decision: string;
+    timestamp: string;
+};
+
+type User = {
+    accountID: number;
+    skinTone: number;
+};
+
+type Reaction = {
+    emoji: string;
+    users: User[];
+};
+
+type OriginalMessageAddComment = {
+    actionName: typeof CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT;
+    originalMessage: {
+        html: string;
+        lastModified?: string;
+        taskReportID?: string;
+        edits?: string[];
+        childReportID?: string;
+        isDeletedParentAction?: boolean;
+        flags?: Record<FlagSeverityName, FlagSeverity[]>;
+        moderationDecisions?: Decision[];
+        whisperedTo: number[];
+        reactions?: Reaction[];
+    };
+};
+
+type OriginalMessageClosed = {
+    actionName: typeof CONST.REPORT.ACTIONS.TYPE.CLOSED;
+    originalMessage: {
+        policyName: string;
+        reason: 'default' | 'accountClosed' | 'accountMerged' | 'removedPolicy' | 'policyDeleted';
+        lastModified?: string;
+    };
+};
+
+type OriginalMessageCreated = {
+    actionName: typeof CONST.REPORT.ACTIONS.TYPE.CREATED;
+    originalMessage: unknown;
+};
+
+type OriginalMessageRenamed = {
+    actionName: typeof CONST.REPORT.ACTIONS.TYPE.RENAMED;
+    originalMessage: {
+        html: string;
+        lastModified: string;
+        oldName: string;
+        newName: string;
+    };
+};
+
+type ChronosOOOTimestamp = {
+    date: string;
+    timezone: string;
+    // eslint-disable-next-line @typescript-eslint/naming-convention
+    timezone_type: number;
+};
+
+type ChronosOOOEvent = {
+    id: string;
+    lengthInDays: number;
+    summary: string;
+    start: ChronosOOOTimestamp;
+    end: ChronosOOOTimestamp;
+};
+
+type OriginalMessageChronosOOOList = {
+    actionName: typeof CONST.REPORT.ACTIONS.TYPE.CHRONOSOOOLIST;
+    originalMessage: {
+        edits: string[];
+        events: ChronosOOOEvent[];
+        html: string;
+        lastModified: string;
+    };
+};
+
+type OriginalMessageReportPreview = {
+    actionName: typeof CONST.REPORT.ACTIONS.TYPE.REPORTPREVIEW;
+    originalMessage: {
+        linkedReportID: string;
+    };
+};
+
+type OriginalMessagePolicyChangeLog = {
+    actionName: ValueOf<typeof CONST.REPORT.ACTIONS.TYPE.POLICYCHANGELOG>;
+    originalMessage: unknown;
+};
+
+type OriginalMessagePolicyTask = {
+    actionName:
+        | typeof CONST.REPORT.ACTIONS.TYPE.TASKEDITED
+        | typeof CONST.REPORT.ACTIONS.TYPE.TASKCANCELLED
+        | typeof CONST.REPORT.ACTIONS.TYPE.TASKCOMPLETED
+        | typeof CONST.REPORT.ACTIONS.TYPE.TASKREOPENED;
+    originalMessage: unknown;
+};
+
+type OriginalMessage =
+    | OriginalMessageIOU
+    | OriginalMessageAddComment
+    | OriginalMessageClosed
+    | OriginalMessageCreated
+    | OriginalMessageRenamed
+    | OriginalMessageChronosOOOList
+    | OriginalMessageReportPreview
+    | OriginalMessagePolicyChangeLog
+    | OriginalMessagePolicyTask;
+
+export default OriginalMessage;
+export type {Reaction};
diff --git a/src/types/onyx/Paypal.ts b/src/types/onyx/Paypal.ts
new file mode 100644
index 000000000000..26236a63b7fc
--- /dev/null
+++ b/src/types/onyx/Paypal.ts
@@ -0,0 +1,27 @@
+import CONST from '../../CONST';
+import * as OnyxCommon from './OnyxCommon';
+
+type PaypalAccountData = {
+    username: string;
+};
+
+type Paypal = {
+    /** This is always 'PayPal.me' */
+    title: string;
+
+    /** The paypalMe address */
+    description: string;
+
+    /** This is always 'payPalMe' */
+    methodID: typeof CONST.PAYMENT_METHODS.PAYPAL;
+
+    /** This is always 'payPalMe' */
+    accountType: typeof CONST.PAYMENT_METHODS.PAYPAL;
+
+    key: string;
+    isDefault: boolean;
+    pendingAction?: OnyxCommon.PendingAction;
+    accountData: PaypalAccountData;
+};
+
+export default Paypal;
diff --git a/src/types/onyx/PersonalBankAccount.ts b/src/types/onyx/PersonalBankAccount.ts
new file mode 100644
index 000000000000..06f505a04196
--- /dev/null
+++ b/src/types/onyx/PersonalBankAccount.ts
@@ -0,0 +1,15 @@
+type PersonalBankAccount = {
+    /** An error message to display to the user */
+    error?: string;
+
+    /** Whether we should show the view that the bank account was successfully added */
+    shouldShowSuccess?: boolean;
+
+    /** Whether the form is loading */
+    isLoading?: boolean;
+
+    /** The account ID of the selected bank account from Plaid */
+    plaidAccountID?: string;
+};
+
+export default PersonalBankAccount;
diff --git a/src/types/onyx/PersonalDetails.ts b/src/types/onyx/PersonalDetails.ts
new file mode 100644
index 000000000000..64911dbfecb1
--- /dev/null
+++ b/src/types/onyx/PersonalDetails.ts
@@ -0,0 +1,45 @@
+type PersonalDetails = {
+    /** ID of the current user from their personal details */
+    accountID: number;
+
+    /** First name of the current user from their personal details */
+    firstName?: string;
+
+    /** Last name of the current user from their personal details */
+    lastName?: string;
+
+    /** Display name of the current user from their personal details */
+    displayName: string;
+
+    /** Is current user validated */
+    validated?: boolean;
+
+    /** Phone number of the current user from their personal details   */
+    phoneNumber?: string;
+
+    /** Avatar URL of the current user from their personal details */
+    avatar: string;
+
+    /** Flag to set when Avatar uploading */
+    avatarUploading?: boolean;
+
+    /** Login of the current user from their personal details */
+    login?: string;
+
+    /** Pronouns of the current user from their personal details */
+    pronouns?: string;
+
+    /** Local currency for the user */
+    localCurrencyCode?: string;
+
+    /** Timezone of the current user from their personal details */
+    timezone?: {
+        /** Value of selected timezone */
+        selected?: string;
+
+        /** Whether timezone is automatically set */
+        automatic?: boolean;
+    };
+};
+
+export default PersonalDetails;
diff --git a/src/types/onyx/PlaidBankAccount.ts b/src/types/onyx/PlaidBankAccount.ts
new file mode 100644
index 000000000000..d89e8ac3082d
--- /dev/null
+++ b/src/types/onyx/PlaidBankAccount.ts
@@ -0,0 +1,24 @@
+type PlaidBankAccount = {
+    /** Masked account number */
+    accountNumber: string;
+
+    /** Name of account */
+    addressName: string;
+
+    /** Is the account a savings account? */
+    isSavings: boolean;
+
+    /** Unique identifier for this account in Plaid */
+    plaidAccountID: string;
+
+    /** Routing number for the account */
+    routingNumber: string;
+
+    /** Last 4 digits of the account number */
+    mask: string;
+
+    /** Plaid access token, used to then retrieve Assets and Balances */
+    plaidAccessToken: string;
+};
+
+export default PlaidBankAccount;
diff --git a/src/types/onyx/PlaidData.ts b/src/types/onyx/PlaidData.ts
new file mode 100644
index 000000000000..a4a6d8e6fe8c
--- /dev/null
+++ b/src/types/onyx/PlaidData.ts
@@ -0,0 +1,21 @@
+import PlaidBankAccount from './PlaidBankAccount';
+import * as OnyxCommon from './OnyxCommon';
+
+type PlaidData = {
+    /** Name of the bank */
+    bankName?: string;
+
+    /**
+     * Access token returned by Plaid once the user has logged into their bank.
+     * This token can be used along with internal credentials to query for Plaid Balance or Assets
+     */
+    plaidAccessToken: string;
+
+    /** List of plaid bank accounts */
+    bankAccounts?: PlaidBankAccount[];
+
+    isLoading?: boolean;
+    errors: OnyxCommon.Errors;
+};
+
+export default PlaidData;
diff --git a/src/types/onyx/Policy.ts b/src/types/onyx/Policy.ts
new file mode 100644
index 000000000000..cacbb5d15199
--- /dev/null
+++ b/src/types/onyx/Policy.ts
@@ -0,0 +1,37 @@
+import {ValueOf} from 'type-fest';
+import CONST from '../../CONST';
+import * as OnyxCommon from './OnyxCommon';
+
+type Policy = {
+    /** The ID of the policy */
+    id?: string;
+
+    /** The name of the policy */
+    name?: string;
+
+    /** The current user's role in the policy */
+    role?: ValueOf<typeof CONST.POLICY.ROLE>;
+
+    /** The policy type */
+    type?: ValueOf<typeof CONST.POLICY.TYPE>;
+
+    /** The email of the policy owner */
+    owner?: string;
+
+    /** The output currency for the policy */
+    outputCurrency?: string;
+
+    /** The URL for the policy avatar */
+    avatar?: string;
+
+    /** Error objects keyed by field name containing errors keyed by microtime */
+    errorFields?: OnyxCommon.ErrorFields;
+
+    pendingAction?: OnyxCommon.PendingAction;
+    errors: OnyxCommon.Errors;
+    isFromFullPolicy?: boolean;
+    lastModified?: string;
+    customUnits?: Record<string, unknown>;
+};
+
+export default Policy;
diff --git a/src/types/onyx/PolicyMember.ts b/src/types/onyx/PolicyMember.ts
new file mode 100644
index 000000000000..055465020c36
--- /dev/null
+++ b/src/types/onyx/PolicyMember.ts
@@ -0,0 +1,17 @@
+import * as OnyxCommon from './OnyxCommon';
+
+type PolicyMember = {
+    /** Role of the user in the policy */
+    role?: string;
+
+    /**
+     * Errors from api calls on the specific user
+     * {<timestamp>: 'error message', <timestamp2>: 'error message 2'}
+     */
+    errors?: OnyxCommon.Errors;
+
+    /** Is this action pending? */
+    pendingAction?: OnyxCommon.PendingAction;
+};
+
+export default PolicyMember;
diff --git a/src/types/onyx/PrivatePersonalDetails.ts b/src/types/onyx/PrivatePersonalDetails.ts
new file mode 100644
index 000000000000..50ec77212efd
--- /dev/null
+++ b/src/types/onyx/PrivatePersonalDetails.ts
@@ -0,0 +1,18 @@
+type Address = {
+    street: string;
+    city: string;
+    state: string;
+    zip: string;
+    country: string;
+};
+
+type PrivatePersonalDetails = {
+    legalFirstName?: string;
+    legalLastName?: string;
+    dob?: string;
+
+    /** User's home address */
+    address?: Address;
+};
+
+export default PrivatePersonalDetails;
diff --git a/src/types/onyx/QueuedOnyxUpdates.ts b/src/types/onyx/QueuedOnyxUpdates.ts
new file mode 100644
index 000000000000..40daa2e09335
--- /dev/null
+++ b/src/types/onyx/QueuedOnyxUpdates.ts
@@ -0,0 +1,5 @@
+import Onyx from 'react-native-onyx';
+
+type QueuedOnyxUpdates = Array<typeof Onyx.update>;
+
+export default QueuedOnyxUpdates;
diff --git a/src/types/onyx/ReceiptModal.ts b/src/types/onyx/ReceiptModal.ts
new file mode 100644
index 000000000000..0d52f684b4d2
--- /dev/null
+++ b/src/types/onyx/ReceiptModal.ts
@@ -0,0 +1,7 @@
+type ReceiptModal = {
+    isAttachmentInvalid: boolean;
+    attachmentInvalidReasonTitle: string;
+    attachmentInvalidReason: string;
+};
+
+export default ReceiptModal;
diff --git a/src/types/onyx/ReimbursementAccount.ts b/src/types/onyx/ReimbursementAccount.ts
new file mode 100644
index 000000000000..4f2a05d7f4e1
--- /dev/null
+++ b/src/types/onyx/ReimbursementAccount.ts
@@ -0,0 +1,44 @@
+import {ValueOf} from 'type-fest';
+import * as OnyxCommon from './OnyxCommon';
+import CONST from '../../CONST';
+
+type ACHData = {
+    /** Step of the setup flow that we are on. Determines which view is presented. */
+    currentStep: ValueOf<typeof CONST.BANK_ACCOUNT.STEP>;
+
+    /** Optional subStep we would like the user to start back on */
+    subStep?: ValueOf<typeof CONST.BANK_ACCOUNT.SUBSTEP>;
+
+    /** Bank account state */
+    state?: string;
+
+    /** Bank account ID of the VBA that we are validating is required */
+    bankAccountID?: number;
+};
+
+type ReimbursementAccount = {
+    /** Whether we are loading the data via the API */
+    isLoading?: boolean;
+
+    /** A date that indicates the user has been throttled */
+    throttledDate?: string;
+
+    /** Additional data for the account in setup */
+    achData?: ACHData;
+
+    /** Disable validation button if max attempts exceeded */
+    maxAttemptsReached?: boolean;
+
+    /** Alert message to display above submit button */
+    error?: string;
+
+    /** Which field needs attention? */
+    errorFields?: OnyxCommon.ErrorFields;
+
+    /** Any additional error message to show */
+    errors?: OnyxCommon.Errors;
+
+    pendingAction?: OnyxCommon.PendingAction;
+};
+
+export default ReimbursementAccount;
diff --git a/src/types/onyx/ReimbursementAccountDraft.ts b/src/types/onyx/ReimbursementAccountDraft.ts
new file mode 100644
index 000000000000..d55c2b5b3567
--- /dev/null
+++ b/src/types/onyx/ReimbursementAccountDraft.ts
@@ -0,0 +1,30 @@
+type ReimbursementAccountDraft = {
+    accountNumber?: string;
+    routingNumber?: string;
+    acceptTerms?: boolean;
+    plaidAccountID?: string;
+    plaidMask?: string;
+    companyName?: string;
+    companyPhone?: string;
+    website?: string;
+    companyTaxID?: string;
+    incorporationType?: string;
+    incorporationDate?: string | Date;
+    incorporationState?: string;
+    hasNoConnectionToCannabis?: boolean;
+    isControllingOfficer?: boolean;
+    isOnfidoSetupComplete?: boolean;
+    ownsMoreThan25Percent?: boolean;
+    hasOtherBeneficialOwners?: boolean;
+    acceptTermsAndConditions?: boolean;
+    certifyTrueInformation?: boolean;
+    beneficialOwners?: string[];
+    isSavings?: boolean;
+    bankName?: string;
+    plaidAccessToken?: string;
+    amount1?: string;
+    amount2?: string;
+    amount3?: string;
+};
+
+export default ReimbursementAccountDraft;
diff --git a/src/types/onyx/Report.ts b/src/types/onyx/Report.ts
new file mode 100644
index 000000000000..8660837ba874
--- /dev/null
+++ b/src/types/onyx/Report.ts
@@ -0,0 +1,86 @@
+import {ValueOf} from 'type-fest';
+import CONST from '../../CONST';
+import * as OnyxCommon from './OnyxCommon';
+
+type Report = {
+    /** The specific type of chat */
+    chatType?: ValueOf<typeof CONST.REPORT.CHAT_TYPE>;
+
+    /** Whether there is an outstanding amount in IOU */
+    hasOutstandingIOU?: boolean;
+
+    /** List of icons for report participants */
+    icons?: OnyxCommon.Icon[];
+
+    /** Are we loading more report actions? */
+    isLoadingMoreReportActions?: boolean;
+
+    /** Flag to check if the report actions data are loading */
+    isLoadingReportActions?: boolean;
+
+    /** Whether the user is not an admin of policyExpenseChat chat */
+    isOwnPolicyExpenseChat?: boolean;
+
+    /** Indicates if the report is pinned to the LHN or not */
+    isPinned?: boolean;
+
+    /** The email of the last message's actor */
+    lastActorEmail?: string;
+
+    /** The text of the last message on the report */
+    lastMessageText?: string;
+
+    /** The time of the last message on the report */
+    lastVisibleActionCreated?: string;
+
+    /** The last time the report was visited */
+    lastReadTime?: string;
+
+    /** The current user's notification preference for this report */
+    notificationPreference?: string | number;
+
+    /** The policy name to use for an archived report */
+    oldPolicyName?: string;
+
+    /** The email address of the report owner */
+    ownerEmail?: string;
+
+    /** List of primarylogins of participants of the report */
+    participants?: string[];
+
+    /** Linked policy's ID */
+    policyID?: string;
+
+    /** Name of the report */
+    reportName?: string;
+
+    /** ID of the report */
+    reportID?: string;
+
+    /** The state that the report is currently in */
+    stateNum?: ValueOf<typeof CONST.REPORT.STATE_NUM>;
+
+    /** The status of the current report */
+    statusNum?: ValueOf<typeof CONST.REPORT.STATUS>;
+
+    /** Which user role is capable of posting messages on the report */
+    writeCapability?: ValueOf<typeof CONST.REPORT.WRITE_CAPABILITIES>;
+
+    /** The report type */
+    type?: string;
+
+    parentReportID?: string;
+    parentReportActionID?: string;
+    isOptimisticReport?: boolean;
+    hasDraft?: boolean;
+    managerID?: number;
+    lastVisibleActionLastModified?: string;
+    displayName?: string;
+    lastMessageHtml?: string;
+    welcomeMessage?: string;
+    lastActorAccountID?: number;
+    ownerAccountID?: number;
+    participantAccountIDs?: number[];
+};
+
+export default Report;
diff --git a/src/types/onyx/ReportAction.ts b/src/types/onyx/ReportAction.ts
new file mode 100644
index 000000000000..5f0072959917
--- /dev/null
+++ b/src/types/onyx/ReportAction.ts
@@ -0,0 +1,85 @@
+import OriginalMessage, {Reaction} from './OriginalMessage';
+import * as OnyxCommon from './OnyxCommon';
+
+type Message = {
+    /** The type of the action item fragment. Used to render a corresponding component */
+    type: string;
+
+    /** The text content of the fragment. */
+    text: string;
+
+    /** Used to apply additional styling. Style refers to a predetermined constant and not a class name. e.g. 'normal'
+     * or 'strong'
+     */
+    style?: string;
+
+    /** ID of a report */
+    reportID?: string;
+
+    /** ID of a policy */
+    policyID?: string;
+
+    /** The target of a link fragment e.g. '_blank' */
+    target?: string;
+
+    /** The destination of a link fragment e.g. 'https://www.expensify.com' */
+    href?: string;
+
+    /** An additional avatar url - not the main avatar url but used within a message. */
+    iconUrl?: string;
+
+    /** Fragment edited flag */
+    isEdited: boolean;
+
+    isDeletedParentAction: boolean;
+    whisperedTo: number[];
+    reactions: Reaction[];
+};
+
+type Person = {
+    type?: string;
+    style?: string;
+    text?: string;
+};
+
+type ReportActionBase = {
+    /** The ID of the reportAction. It is the string representation of the a 64-bit integer. */
+    reportActionID?: string;
+
+    actorAccountID?: number;
+
+    /** Person who created the action */
+    person?: Person[];
+
+    /** ISO-formatted datetime */
+    created?: string;
+
+    /** report action message */
+    message?: Message[];
+
+    /** Whether we have received a response back from the server */
+    isLoading?: boolean;
+
+    /** Error message that's come back from the server. */
+    error?: string;
+
+    /** accountIDs of the people to which the whisper was sent to (if any). Returns empty array if it is not a whisper */
+    whisperedToAccountIDs?: number[];
+
+    avatar?: string;
+    automatic?: boolean;
+    shouldShow?: boolean;
+    childReportID?: string;
+    childType?: string;
+    childOldestFourEmails?: string;
+    childOldestFourAccountIDs?: string;
+    childCommenterCount?: number;
+    childLastVisibleActionCreated?: string;
+    childVisibleActionCount?: number;
+
+    pendingAction?: OnyxCommon.PendingAction;
+};
+
+type ReportAction = ReportActionBase & OriginalMessage;
+
+export default ReportAction;
diff --git a/src/types/onyx/ReportActionReactions.ts b/src/types/onyx/ReportActionReactions.ts
new file mode 100644
index 000000000000..196e2707bbd2
--- /dev/null
+++ b/src/types/onyx/ReportActionReactions.ts
@@ -0,0 +1,15 @@
+type User = {
+    /** The skin tone which was used and also the timestamp of when it was added */
+    skinTones: Record<string, string>;
+};
+
+type ReportActionReaction = {
+    /** The time the emoji was added */
+    createdAt: string;
+    /** All the users who have added this emoji */
+    users: Record<number, User>;
+};
+
+type ReportActionReactions = Record<string, ReportActionReaction>;
+
+export default ReportActionReactions;
diff --git a/src/types/onyx/Request.ts b/src/types/onyx/Request.ts
new file mode 100644
index 000000000000..e730dfd807fb
--- /dev/null
+++ b/src/types/onyx/Request.ts
@@ -0,0 +1,8 @@
+type Request = {
+    command?: string;
+    data?: Record<string, unknown>;
+    type?: string;
+    shouldUseSecure?: boolean;
+};
+
+export default Request;
diff --git a/src/types/onyx/ScreenShareRequest.ts b/src/types/onyx/ScreenShareRequest.ts
new file mode 100644
index 000000000000..564ba99c22ac
--- /dev/null
+++ b/src/types/onyx/ScreenShareRequest.ts
@@ -0,0 +1,9 @@
+type ScreenShareRequest = {
+    /** Access token required to join a screen share room, generated by the backend */
+    accessToken: string;
+
+    /** Name of the screen share room to join */
+    roomName: string;
+};
+
+export default ScreenShareRequest;
diff --git a/src/types/onyx/SecurityGroup.ts b/src/types/onyx/SecurityGroup.ts
new file mode 100644
index 000000000000..b2362c1eb628
--- /dev/null
+++ b/src/types/onyx/SecurityGroup.ts
@@ -0,0 +1,5 @@
+type SecurityGroup = {
+    hasRestrictedPrimaryLogin: boolean;
+};
+
+export default SecurityGroup;
diff --git a/src/types/onyx/Session.ts b/src/types/onyx/Session.ts
new file mode 100644
index 000000000000..75cb4f4818ad
--- /dev/null
+++ b/src/types/onyx/Session.ts
@@ -0,0 +1,17 @@
+type Session = {
+    /** The user's email for the current session */
+    email?: string;
+
+    /** Currently logged in user authToken */
+    authToken?: string;
+
+    /** Currently logged in user encrypted authToken */
+    encryptedAuthToken?: string;
+
+    /** Currently logged in user accountID */
+    accountID?: number;
+
+    autoAuthState?: string;
+};
+
+export default Session;
diff --git a/src/types/onyx/Task.ts b/src/types/onyx/Task.ts
new file mode 100644
index 000000000000..9d5c83ee4a40
--- /dev/null
+++ b/src/types/onyx/Task.ts
@@ -0,0 +1,27 @@
+import Report from './Report';
+
+type Task = {
+    /** Title of the Task */
+    title: string;
+
+    /** Description of the Task */
+    description?: string;
+
+    // TODO: Make sure this field exists in the API
+    /** Share destination of the Task */
+    shareDestination?: string;
+
+    /** The task report if it's currently being edited */
+    report?: Report;
+
+    /** Assignee of the task */
+    assignee?: string;
+
+    /** The account id of the assignee */
+    assigneeAccountID?: number;
+
+    /** Report id only when a task was created from a report */
+    parentReportID?: string;
+};
+
+export default Task;
diff --git a/src/types/onyx/Transaction.ts b/src/types/onyx/Transaction.ts
new file mode 100644
index 000000000000..0e0c7a423829
--- /dev/null
+++ b/src/types/onyx/Transaction.ts
@@ -0,0 +1,22 @@
+import * as OnyxCommon from './OnyxCommon';
+
+type Comment = {
+    comment?: string;
+};
+
+type Transaction = {
+    transactionID: string;
+    amount: number;
+    currency: string;
+    reportID: string;
+    comment: Comment;
+    merchant: string;
+    created: string;
+    pendingAction: OnyxCommon.PendingAction;
+    errors: OnyxCommon.Errors;
+    modifiedAmount?: number;
+    modifiedCreated?: string;
+    modifiedCurrency?: string;
+};
+
+export default Transaction;
diff --git a/src/types/onyx/User.ts b/src/types/onyx/User.ts
new file mode 100644
index 000000000000..f770b22b2272
--- /dev/null
+++ b/src/types/onyx/User.ts
@@ -0,0 +1,30 @@
+type User = {
+    /** Whether or not the user is subscribed to news updates */
+    isSubscribedToNewsletter: boolean;
+
+    /** Whether we should use the staging version of the secure API server */
+    shouldUseStagingServer?: boolean;
+
+    /** Is the user account validated? */
+    validated: boolean;
+
+    /** Whether or not the user is on a public domain email account or not */
+    isFromPublicDomain: boolean;
+
+    /** Whether or not the user use expensify card */
+    isUsingExpensifyCard: boolean;
+
+    /** Whever Expensify Card approval flow is ongoing - checking loginList for private domains */
+    isCheckingDomain?: boolean;
+
+    /** Whether or not the user has lounge access */
+    hasLoungeAccess?: boolean;
+
+    /** error associated with adding a secondary login */
+    error?: string;
+
+    /** Whether the form is being submitted */
+    loading?: boolean;
+};
+
+export default User;
diff --git a/src/types/onyx/UserWallet.ts b/src/types/onyx/UserWallet.ts
new file mode 100644
index 000000000000..8624f16000c9
--- /dev/null
+++ b/src/types/onyx/UserWallet.ts
@@ -0,0 +1,53 @@
+import {ValueOf} from 'type-fest';
+import CONST from '../../CONST';
+import * as OnyxCommon from './OnyxCommon';
+
+type WalletLinkedAccountType = 'debitCard' | 'bankAccount';
+
+type ErrorCode = 'ssnError' | 'kbaNeeded' | 'kycFailed';
+
+type UserWallet = {
+    /** The user's available wallet balance */
+    availableBalance: number;
+
+    /** The user's current wallet balance */
+    currentBalance: number;
+
+    /** What step in the activation flow are we on? */
+    currentStep: ValueOf<typeof CONST.WALLET.STEP>;
+
+    /** If we should show the FailedKYC view after the user submitted their info with a non fixable error */
+    shouldShowFailedKYC?: boolean;
+
+    /** Status of wallet - e.g. SILVER or GOLD */
+    tierName: ValueOf<typeof CONST.WALLET.TIER_NAME>;
+
+    /** The user's wallet tier */
+    tier?: number;
+
+    /** Whether we should show the ActivateStep success view after the user finished the KYC flow */
+    shouldShowWalletActivationSuccess?: boolean;
+
+    /** The ID of the linked account */
+    walletLinkedAccountID: number;
+
+    /** The type of the linked account (debitCard or bankAccount) */
+    walletLinkedAccountType: WalletLinkedAccountType;
+
+    /** The user's bank account ID */
+    bankAccountID?: number;
+
+    /** The user's current wallet limit */
+    walletLimit?: number;
+
+    /** The user's current wallet limit enforcement period */
+    walletLimitEnforcementPeriod?: number;
+
+    /** Error code returned by the server */
+    errorCode?: ErrorCode;
+
+    /** An error message to display to the user */
+    errors?: OnyxCommon.Errors;
+};
+
+export default UserWallet;
diff --git a/src/types/onyx/WalletAdditionalDetails.ts b/src/types/onyx/WalletAdditionalDetails.ts
new file mode 100644
index 000000000000..e766ba4cfe50
--- /dev/null
+++ b/src/types/onyx/WalletAdditionalDetails.ts
@@ -0,0 +1,23 @@
+import * as OnyxCommon from './OnyxCommon';
+
+type WalletAdditionalDetails = {
+    /** Questions returned by Idology */
+    questions?: {
+        prompt: string;
+        type: string;
+        answer: string[];
+    };
+
+    /** ExpectID ID number related to those questions */
+    idNumber?: string;
+
+    /** Error code to determine additional behavior */
+    errorCode?: string;
+
+    /** Which field needs attention? */
+    errorFields?: OnyxCommon.ErrorFields;
+    isLoading?: boolean;
+    errors?: OnyxCommon.Errors;
+};
+
+export default WalletAdditionalDetails;
diff --git a/src/types/onyx/WalletOnfido.ts b/src/types/onyx/WalletOnfido.ts
new file mode 100644
index 000000000000..7a65c0f710ef
--- /dev/null
+++ b/src/types/onyx/WalletOnfido.ts
@@ -0,0 +1,26 @@
+import * as OnyxCommon from './OnyxCommon';
+
+type WalletOnfido = {
+    /** Unique identifier returned from openOnfidoFlow then re-sent to ActivateWallet with Onfido response data */
+    applicantID: string;
+
+    /** Token used to initialize the Onfido SDK token */
+    sdkToken: string;
+
+    /** Loading state to provide feedback when we are waiting for a request to finish */
+    isLoading?: boolean;
+
+    /** Error message to inform the user of any problem that might occur */
+    errors?: OnyxCommon.Errors;
+
+    /** A list of Onfido errors that the user can fix in order to attempt the Onfido flow again */
+    fixableErrors?: string[];
+
+    /** Whether the user has accepted the privacy policy of Onfido or not */
+    hasAcceptedPrivacyPolicy?: boolean;
+
+    /** If we should show the FailedKYC view after the user submitted their info with a non fixable error */
+    shouldShowFailedKYC?: boolean;
+};
+
+export default WalletOnfido;
diff --git a/src/types/onyx/WalletStatement.ts b/src/types/onyx/WalletStatement.ts
new file mode 100644
index 000000000000..d42aae32a823
--- /dev/null
+++ b/src/types/onyx/WalletStatement.ts
@@ -0,0 +1,6 @@
+type WalletStatement = {
+    /** Whether we are currently generating a PDF version of the statement */
+    isGenerating: boolean;
+};
+
+export default WalletStatement;
diff --git a/src/types/onyx/WalletTerms.ts b/src/types/onyx/WalletTerms.ts
new file mode 100644
index 000000000000..5394f126c33c
--- /dev/null
+++ b/src/types/onyx/WalletTerms.ts
@@ -0,0 +1,11 @@
+import * as OnyxCommon from './OnyxCommon';
+
+type WalletTerms = {
+    /** Any error message to show */
+    errors?: OnyxCommon.Errors;
+
+    /** When the user accepts the Wallet's terms in order to pay an IOU, this is the ID of the chatReport the IOU is linked to */
+    chatReportID?: string;
+};
+
+export default WalletTerms;
diff --git a/src/types/onyx/WalletTransfer.ts b/src/types/onyx/WalletTransfer.ts
new file mode 100644
index 000000000000..c5d92250f91d
--- /dev/null
+++ b/src/types/onyx/WalletTransfer.ts
@@ -0,0 +1,26 @@
+import CONST from '../../CONST';
+import * as OnyxCommon from './OnyxCommon';
+
+type WalletTransfer = {
+    /** Selected accountID for transfer */
+    selectedAccountID?: string | number;
+
+    /** Selected accountType for transfer */
+    selectedAccountType?: string;
+
+    /** Type to filter the payment Method list */
+    // TODO: Remove this after CONST.ts is migrated to TS
+    // eslint-disable-next-line @typescript-eslint/no-duplicate-type-constituents
+    filterPaymentMethodType?: typeof CONST.PAYMENT_METHODS.DEBIT_CARD | typeof CONST.PAYMENT_METHODS.BANK_ACCOUNT;
+
+    /** Whether the success screen is shown to user. */
+    shouldShowSuccess?: boolean;
+
+    /** An error message to display to the user */
+    errors?: OnyxCommon.Errors;
+
+    /** Whether or not data is loading */
+    loading?: boolean;
+};
+
+export default WalletTransfer;
diff --git a/src/types/onyx/index.ts b/src/types/onyx/index.ts
new file mode 100644
index 000000000000..e7ab360551c5
--- /dev/null
+++ b/src/types/onyx/index.ts
@@ -0,0 +1,92 @@
+import Account from './Account';
+import Request from './Request';
+import Credentials from './Credentials';
+import QueuedOnyxUpdates from './QueuedOnyxUpdates';
+import IOU from './IOU';
+import Modal from './Modal';
+import Network from './Network';
+import CustomStatusDraft from './CustomStatusDraft';
+import PersonalDetails from './PersonalDetails';
+import PrivatePersonalDetails from './PrivatePersonalDetails';
+import Task from './Task';
+import Currency from './Currency';
+import ScreenShareRequest from './ScreenShareRequest';
+import User from './User';
+import Login from './Login';
+import Session from './Session';
+import Beta from './Beta';
+import Paypal from './Paypal';
+import BlockedFromConcierge from './BlockedFromConcierge';
+import PlaidData from './PlaidData';
+import UserWallet from './UserWallet';
+import WalletOnfido from './WalletOnfido';
+import WalletAdditionalDetails from './WalletAdditionalDetails';
+import WalletTerms from './WalletTerms';
+import BankAccount from './BankAccount';
+import Card from './Card';
+import WalletStatement from './WalletStatement';
+import PersonalBankAccount from './PersonalBankAccount';
+import FrequentlyUsedEmoji from './FrequentlyUsedEmoji';
+import ReimbursementAccount from './ReimbursementAccount';
+import ReimbursementAccountDraft from './ReimbursementAccountDraft';
+import WalletTransfer from './WalletTransfer';
+import ReceiptModal from './ReceiptModal';
+import MapboxAccessToken from './MapboxAccessToken';
+
+import Download from './Download';
+import PolicyMember from './PolicyMember';
+import Policy from './Policy';
+import Report from './Report';
+import ReportAction from './ReportAction';
+import ReportActionReactions from './ReportActionReactions';
+import SecurityGroup from './SecurityGroup';
+import Transaction from './Transaction';
+
+import Form, {AddDebitCardForm} from './Form';
+
+export type {
+    Account,
+    Request,
+    Credentials,
+    QueuedOnyxUpdates,
+    IOU,
+    Modal,
+    Network,
+    CustomStatusDraft,
+    PersonalDetails,
+    PrivatePersonalDetails,
+    Task,
+    Currency,
+    ScreenShareRequest,
+    User,
+    Login,
+    Session,
+    Beta,
+    Paypal,
+    BlockedFromConcierge,
+    PlaidData,
+    UserWallet,
+    WalletOnfido,
+    WalletAdditionalDetails,
+    WalletTerms,
+    BankAccount,
+    Card,
+    WalletStatement,
+    PersonalBankAccount,
+    ReimbursementAccount,
+    ReimbursementAccountDraft,
+    FrequentlyUsedEmoji,
+    WalletTransfer,
+    ReceiptModal,
+    MapboxAccessToken,
+    Download,
+    PolicyMember,
+    Policy,
+    Report,
+    ReportAction,
+    ReportActionReactions,
+    SecurityGroup,
+    Transaction,
+    Form,
+    AddDebitCardForm,
+};
diff --git a/src/types/utils/DeepValueOf.ts b/src/types/utils/DeepValueOf.ts
new file mode 100644
index 000000000000..eb44eac7e751
--- /dev/null
+++ b/src/types/utils/DeepValueOf.ts
@@ -0,0 +1,4 @@
+// eslint-disable-next-line @typescript-eslint/ban-types
+type DeepValueOf<T> = T extends object ? DeepValueOf<T[keyof T]> : T;
+
+export default DeepValueOf;
