From 0c54e07901360ade24a8c78da2fb853839710644 Mon Sep 17 00:00:00 2001 From: Brian Arthur Cooper Date: Thu, 20 Jun 2024 10:46:37 -0400 Subject: [PATCH] style(app, protocol-designer, components): promote no-unsafe-argument from warn to error, fix all (#15402) Promote the typescript eslint rule for no-unsafe-argument to error and fix all outstanding instances in the mono repo --- .eslintrc.js | 3 +- .github/workflows/js-check.yaml | 6 +- Makefile | 2 +- app-shell-odd/src/config/index.ts | 4 +- app-shell-odd/src/log.ts | 3 +- app-shell-odd/src/main.ts | 7 +- .../src/notifications/deserialize.ts | 2 +- app-shell-odd/src/system-update/index.ts | 2 +- app-shell/src/config/index.ts | 2 +- app-shell/src/log.ts | 2 +- app-shell/src/main.ts | 7 +- app-shell/src/notifications/deserialize.ts | 2 +- .../protocol-analysis/executeAnalyzeCli.ts | 2 +- app-shell/src/protocol-analysis/index.ts | 2 +- app-shell/src/protocol-storage/file-system.ts | 2 +- app-shell/src/usb.ts | 6 +- app/src/App/DesktopAppFallback.tsx | 2 +- app/src/App/OnDeviceDisplayAppFallback.tsx | 2 +- app/src/App/hooks.ts | 2 +- app/src/i18n.ts | 2 +- app/src/molecules/Command/CommandText.tsx | 13 +-- .../Command/MoveLabwareCommandText.tsx | 7 +- .../Command/PipettingCommandText.tsx | 15 +-- .../GenericWizardTile.stories.tsx | 7 +- .../InterventionModal.stories.tsx | 7 +- .../SimpleWizardBody.stories.tsx | 7 +- .../ClearUnavailableRobots.tsx | 7 +- app/src/organisms/Alerts/AlertsModal.tsx | 4 +- .../AppSettings/ConnectRobotSlideout.tsx | 4 +- .../LabwareOffsetTable.tsx | 8 +- .../ChooseProtocolSlideout/index.tsx | 12 +-- .../organisms/ChooseRobotSlideout/index.tsx | 12 +-- .../ProtocolRun/SetupLabware/index.tsx | 4 +- .../CurrentOffsetsTable.tsx | 7 +- .../ProtocolRun/SetupLiquids/index.tsx | 4 +- .../ProtocolRun/SetupModuleAndDeck/index.tsx | 4 +- .../AdvancedTab/Troubleshooting.tsx | 4 +- .../Devices/hooks/useDownloadRunLog.ts | 13 ++- .../hooks/useProtocolRunAnalyticsData.ts | 7 +- .../DesktopEstopMissingModal.stories.tsx | 7 +- .../DesktopEstopPressedModal.stories.tsx | 7 +- .../TouchscreenEstopMissingModal.stories.tsx | 7 +- .../TouchscreenEstopPressedModal.stories.tsx | 7 +- .../GripperWizardFlows/BeforeBeginning.tsx | 2 +- .../GripperWizardFlows.stories.tsx | 7 +- .../organisms/GripperWizardFlows/MovePin.tsx | 10 +- .../organisms/GripperWizardFlows/index.tsx | 2 +- .../IncompatibleModuleODDModalBody.tsx | 2 +- .../InterventionModal.stories.tsx | 7 +- .../LabwarePositionCheck/AttachProbe.tsx | 4 +- .../LabwarePositionCheck/CheckItem.tsx | 14 ++- .../LabwarePositionCheck/DetachProbe.tsx | 2 +- .../LabwarePositionCheckComponent.tsx | 6 +- .../LabwarePositionCheck/PickUpTip.tsx | 21 +++-- .../LabwarePositionCheck/ResultsSummary.tsx | 8 +- .../LabwarePositionCheck/ReturnTip.tsx | 15 +-- app/src/organisms/ModuleCard/index.tsx | 10 +- .../PipetteWizardFlows/AttachProbe.tsx | 22 +++-- .../PipetteWizardFlows/BeforeBeginning.tsx | 32 ++++--- .../organisms/PipetteWizardFlows/Carriage.tsx | 10 +- .../PipetteWizardFlows/ChoosePipette.tsx | 4 +- .../PipetteWizardFlows/DetachPipette.tsx | 12 +-- .../PipetteWizardFlows/ExitModal.tsx | 5 +- .../PipetteWizardFlows/MountingPlate.tsx | 6 +- .../organisms/PipetteWizardFlows/Results.tsx | 20 ++-- .../organisms/PipetteWizardFlows/index.tsx | 5 +- .../ModuleTable.tsx | 4 +- .../ProtocolSetupParameters/ChooseEnum.tsx | 2 +- .../ProtocolSetupParameters/ChooseNumber.tsx | 6 +- .../ViewOnlyParameters.tsx | 2 +- .../QuickTransferFlow/SelectDestWells.tsx | 2 +- .../RobotSettingsJoinOtherNetwork.tsx | 2 +- .../pages/ConnectViaWifi/JoinOtherNetwork.tsx | 2 +- app/src/pages/Labware/index.tsx | 12 ++- .../DeleteProtocolConfirmationModal.tsx | 2 +- .../ProtocolDashboard/LongPressModal.tsx | 4 +- app/src/pages/ProtocolDetails/Hardware.tsx | 2 +- app/src/pages/ProtocolDetails/Parameters.tsx | 2 +- app/src/pages/ProtocolDetails/index.tsx | 4 +- app/src/pages/ProtocolSetup/index.tsx | 4 +- app/src/redux/analytics/epic.ts | 13 ++- app/src/redux/analytics/mixpanel.ts | 16 ++-- .../epic/fetchCalibrationStatusEpic.ts | 15 ++- .../fetchPipetteOffsetCalibrationsEpic.ts | 14 ++- .../epic/fetchTipLengthCalibrationsEpic.ts | 14 ++- app/src/redux/discovery/epic.ts | 9 +- .../redux/modules/epic/updateModuleEpic.ts | 15 ++- .../redux/networking/epic/disconnectEpic.ts | 7 +- .../networking/epic/fetchEapOptionsEpic.ts | 7 +- .../networking/epic/fetchWifiKeysEpic.ts | 7 +- .../redux/networking/epic/postWifiKeysEpic.ts | 3 +- app/src/redux/networking/epic/statusEpic.ts | 16 +++- .../networking/epic/wifiConfigureEpic.ts | 9 +- .../pipettes/epic/fetchPipetteSettingsEpic.ts | 14 ++- .../redux/pipettes/epic/fetchPipettesEpic.ts | 13 ++- .../epic/updatePipetteSettingsEpic.ts | 14 ++- app/src/redux/reducer.ts | 9 +- .../robot-admin/epic/fetchResetOptionsEpic.ts | 6 +- .../redux/robot-admin/epic/resetConfigEpic.ts | 6 +- app/src/redux/robot-admin/epic/restartEpic.ts | 8 +- .../robot-admin/epic/syncSystemTimeEpic.ts | 10 +- .../robot-controls/epic/fetchLightsEpic.ts | 4 +- app/src/redux/robot-controls/epic/homeEpic.ts | 2 +- app/src/redux/robot-controls/epic/moveEpic.ts | 10 +- .../robot-controls/epic/updateLightsEpic.ts | 4 +- .../robot-settings/epic/fetchSettingsEpic.ts | 8 +- .../robot-settings/epic/updateSettingEpic.ts | 8 +- app/src/redux/robot-update/epic.ts | 29 +++--- .../sessions/epic/createSessionCommandEpic.ts | 6 +- .../redux/sessions/epic/createSessionEpic.ts | 15 ++- .../redux/sessions/epic/deleteSessionEpic.ts | 7 +- .../sessions/epic/fetchAllSessionsEpic.ts | 19 +++- .../redux/sessions/epic/fetchSessionEpic.ts | 15 ++- app/src/redux/shell/epic.ts | 5 +- app/src/redux/store.ts | 14 ++- components/src/forms/RadioGroup.stories.tsx | 8 +- components/src/primitives/style-props.ts | 2 +- .../organisms/CreateLabwareSandbox/index.tsx | 14 ++- labware-library/src/analytics/utils.ts | 7 +- .../labware-creator/components/Dropdown.tsx | 5 +- .../labware-creator/components/RadioField.tsx | 4 +- .../labware-creator/components/TextField.tsx | 8 +- .../src/labware-creator/fieldsToLabware.ts | 4 +- .../src/labware-creator/formSelectors.ts | 56 +++++++---- .../src/labware-creator/labwareDefToFields.ts | 13 +-- .../src/labware-creator/labwareFormSchema.ts | 29 +++--- opentrons-ai-client/src/i18n.ts | 6 +- .../src/molecules/InputPrompt/index.tsx | 8 +- protocol-designer/src/analytics/middleware.ts | 18 ++-- protocol-designer/src/analytics/mixpanel.ts | 20 ++-- .../utils/flattenNestedProperties.ts | 15 ++- .../LabwareOverlays/EditLabwareOffDeck.tsx | 2 +- .../components/FileSidebar/FileSidebar.tsx | 2 +- .../src/components/IngredientsList/index.tsx | 20 ++-- .../LiquidPlacementForm.tsx | 30 +++--- .../components/LiquidsPage/LiquidEditForm.tsx | 15 +-- .../WellSelectionField/WellSelectionModal.tsx | 11 ++- .../StepSelectionBannerComponent.tsx | 2 +- .../modals/CreateFileWizard/index.tsx | 6 +- .../modals/FilePipettesModal/index.tsx | 1 + .../steplist/DraggableStepItems.tsx | 2 +- protocol-designer/src/configureStore.ts | 20 +++- protocol-designer/src/initialize.ts | 5 +- .../src/load-file/migration/1_1_0.ts | 2 +- .../src/load-file/migration/4_0_0.ts | 5 +- .../src/load-file/migration/5_0_0.ts | 5 +- .../src/load-file/migration/5_1_0.ts | 5 +- .../src/load-file/migration/5_2_0.ts | 5 +- .../src/load-file/migration/8_1_0.ts | 2 +- protocol-designer/src/localization/index.ts | 2 +- protocol-designer/src/persist.ts | 3 +- .../src/step-forms/reducers/index.ts | 70 +++++++++----- .../src/step-forms/selectors/index.ts | 14 +-- .../src/step-forms/utils/index.ts | 4 +- .../src/steplist/formLevel/errors.ts | 37 +++++--- .../dependentFieldsUpdateMix.ts | 4 +- .../dependentFieldsUpdateMoveLiquid.ts | 92 +++++++++++-------- .../formLevel/handleFormChange/utils.ts | 6 +- .../src/steplist/formLevel/profileErrors.ts | 2 +- .../formLevel/stepFormToArgs/index.ts | 40 +++++--- .../stepFormToArgs/pauseFormToArgs.ts | 20 ++-- .../src/steplist/formLevel/warnings.tsx | 13 ++- .../makeTimelineMiddleware.ts | 14 ++- .../src/timelineMiddleware/worker.ts | 11 ++- protocol-designer/src/tutorial/reducers.ts | 2 +- protocol-designer/src/ui/labware/utils.ts | 2 +- shared-data/js/protocols.ts | 32 +++---- yarn.lock | 34 ++----- 168 files changed, 1015 insertions(+), 627 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 99151bd8b87..5af0e54a419 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -101,7 +101,6 @@ module.exports = { '@typescript-eslint/no-floating-promises': 'warn', '@typescript-eslint/no-unnecessary-type-assertion': 'warn', '@typescript-eslint/no-unnecessary-boolean-literal-compare': 'warn', - '@typescript-eslint/no-unsafe-argument': 'warn', '@typescript-eslint/consistent-indexed-object-style': 'warn', '@typescript-eslint/ban-types': 'warn', '@typescript-eslint/non-nullable-type-assertion-style': 'warn', @@ -126,11 +125,13 @@ module.exports = { '**/__fixtures__/**.@(js|ts|tsx)', '**/fixtures/**.@(js|ts|tsx)', 'scripts/*.@(js|ts|tsx)', + '**/**test.@(js|ts|tsx)', ], rules: { '@typescript-eslint/consistent-type-assertions': 'off', '@typescript-eslint/no-var-requires': 'off', '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/no-unsafe-argument': 'off', '@typescript-eslint/no-confusing-void-expression': 'warn', 'node/handle-callback-err': 'off', }, diff --git a/.github/workflows/js-check.yaml b/.github/workflows/js-check.yaml index 8a02c1823ba..139d3b618ad 100644 --- a/.github/workflows/js-check.yaml +++ b/.github/workflows/js-check.yaml @@ -75,12 +75,12 @@ jobs: make setup-js # Use the if to run all the lint checks even of some fail shell: bash - - name: 'lint js' - if: always() && steps.setup-js.outcome == 'success' - run: make lint-js - name: 'typechecks' if: always() && steps.setup-js.outcome == 'success' run: make check-js + - name: 'lint js' + if: always() && steps.setup-js.outcome == 'success' + run: make lint-js - name: 'circular deps' if: always() && steps.setup-js.outcome == 'success' run: make circular-dependencies-js diff --git a/Makefile b/Makefile index c24e2751137..ffdbb8509c0 100755 --- a/Makefile +++ b/Makefile @@ -219,7 +219,7 @@ lint-js: lint-js-eslint lint-js-prettier .PHONY: lint-js-eslint lint-js-eslint: - yarn eslint --quiet=$(quiet) --ignore-pattern "node_modules/" --cache ".*.@(js|ts|tsx)" "**/*.@(js|ts|tsx)" + yarn eslint --quiet=$(quiet) --ignore-pattern "node_modules/" ".*.@(js|ts|tsx)" "**/*.@(js|ts|tsx)" .PHONY: lint-js-prettier lint-js-prettier: diff --git a/app-shell-odd/src/config/index.ts b/app-shell-odd/src/config/index.ts index 99021414f62..4e93472a18e 100644 --- a/app-shell-odd/src/config/index.ts +++ b/app-shell-odd/src/config/index.ts @@ -122,8 +122,8 @@ export function getOverrides(path?: string): unknown { export function getConfig

(path: P): Config[P] export function getConfig(): Config -export function getConfig(path?: any): any { - const result = store().get(path) +export function getConfig(path?: string): any { + const result = path == null ? null : store().get(path) const over = getOverrides(path) if (over != null) { diff --git a/app-shell-odd/src/log.ts b/app-shell-odd/src/log.ts index 181e63b88d3..4312000f424 100644 --- a/app-shell-odd/src/log.ts +++ b/app-shell-odd/src/log.ts @@ -91,7 +91,8 @@ function createTransports(): Transport[] { format: winston.format.combine( winston.format.printf(info => { const { level, message, timestamp, label } = info - const time = timeFromStamp(timestamp) + const time = + typeof timestamp === 'string' ? timeFromStamp(timestamp) : '' // eslint-disable-next-line @typescript-eslint/restrict-template-expressions const print = `${time} [${label}] ${level}: ${message}` const meta = inspect(info.meta, { depth: 6 }) diff --git a/app-shell-odd/src/main.ts b/app-shell-odd/src/main.ts index 6a9067f9075..91e6c8d0d73 100644 --- a/app-shell-odd/src/main.ts +++ b/app-shell-odd/src/main.ts @@ -30,7 +30,8 @@ import { } from './notifications' import type { BrowserWindow } from 'electron' -import type { Dispatch, Logger } from './types' +import type { Action, Dispatch, Logger } from './types' +import type { LogEntry } from 'winston' /** * node 17 introduced a change to default IP resolving to prefer IPv6 which causes localhost requests to fail @@ -121,7 +122,7 @@ function startUp(): void { ipcMain.on('dispatch', (_, action) => { log.debug('Received action via IPC from renderer', { action }) actionHandlers.forEach(handler => { - handler(action) + handler(action as Action) }) }) @@ -147,7 +148,7 @@ function createRendererLogger(): Logger { log.info('Creating renderer logger') const logger = createLogger('renderer') - ipcMain.on('log', (_, info) => logger.log(info)) + ipcMain.on('log', (_, info) => logger.log(info as LogEntry)) return logger } diff --git a/app-shell-odd/src/notifications/deserialize.ts b/app-shell-odd/src/notifications/deserialize.ts index 5a154ebee5f..124ed759983 100644 --- a/app-shell-odd/src/notifications/deserialize.ts +++ b/app-shell-odd/src/notifications/deserialize.ts @@ -60,7 +60,7 @@ export function deserializeExpectedMessages( if (!isValidNotifyResponse) { reject(error) } else { - resolve(JSON.parse(message)) + resolve(JSON.parse(message) as NotifyBrokerResponses) } }) } diff --git a/app-shell-odd/src/system-update/index.ts b/app-shell-odd/src/system-update/index.ts index 399720f0bf0..2d0b53e35e6 100644 --- a/app-shell-odd/src/system-update/index.ts +++ b/app-shell-odd/src/system-update/index.ts @@ -172,7 +172,7 @@ const getVersionFromOpenedZipIfValid = (zip: StreamZip): Promise => reject(new Error('not a Flex release file')) } const fileVersion = parsedContents?.opentrons_api_version - const version = Semver.valid(fileVersion) + const version = Semver.valid(fileVersion as string) if (version === null) { reject(new Error(`${fileVersion} is not a valid version`)) } else { diff --git a/app-shell/src/config/index.ts b/app-shell/src/config/index.ts index 232b8ab829f..72daed31f31 100644 --- a/app-shell/src/config/index.ts +++ b/app-shell/src/config/index.ts @@ -102,7 +102,7 @@ export function getConfig

(path: P): Config[P] export function getConfig(): Config export function getConfig(path?: any): any { const result = store().get(path) - const over = getOverrides(path) + const over = getOverrides(path as string | undefined) if (over != null) { if (typeof result === 'object' && result != null) { diff --git a/app-shell/src/log.ts b/app-shell/src/log.ts index f18e0c0ea52..80128f3d135 100644 --- a/app-shell/src/log.ts +++ b/app-shell/src/log.ts @@ -91,7 +91,7 @@ function createTransports(): Transport[] { format: winston.format.combine( winston.format.printf(info => { const { level, message, timestamp, label } = info - const time = timeFromStamp(timestamp) + const time = timeFromStamp(timestamp as string) // eslint-disable-next-line @typescript-eslint/restrict-template-expressions const print = `${time} [${label}] ${level}: ${message}` const meta = inspect(info.meta, { depth: 6 }) diff --git a/app-shell/src/main.ts b/app-shell/src/main.ts index 21ab2c80117..10d3f02cda0 100644 --- a/app-shell/src/main.ts +++ b/app-shell/src/main.ts @@ -20,7 +20,8 @@ import { registerUsb } from './usb' import { registerNotify, closeAllNotifyConnections } from './notifications' import type { BrowserWindow } from 'electron' -import type { Dispatch, Logger } from './types' +import type { Action, Dispatch, Logger } from './types' +import type { LogEntry } from 'winston' /** * node 17 introduced a change to default IP resolving to prefer IPv6 which causes localhost requests to fail @@ -114,7 +115,7 @@ function startUp(): void { ipcMain.on('dispatch', (_, action) => { log.debug('Received action via IPC from renderer', { action }) actionHandlers.forEach(handler => { - handler(action) + handler(action as Action) }) }) @@ -125,7 +126,7 @@ function createRendererLogger(): Logger { log.info('Creating renderer logger') const logger = createLogger('renderer') - ipcMain.on('log', (_, info) => logger.log(info)) + ipcMain.on('log', (_, info) => logger.log(info as LogEntry)) return logger } diff --git a/app-shell/src/notifications/deserialize.ts b/app-shell/src/notifications/deserialize.ts index 9743f1c3e5c..c9a23511229 100644 --- a/app-shell/src/notifications/deserialize.ts +++ b/app-shell/src/notifications/deserialize.ts @@ -73,7 +73,7 @@ export function deserializeExpectedMessages( if (!isValidNotifyResponse) { reject(error) } else { - resolve(JSON.parse(message)) + resolve(JSON.parse(message) as NotifyBrokerResponses) } }) } diff --git a/app-shell/src/protocol-analysis/executeAnalyzeCli.ts b/app-shell/src/protocol-analysis/executeAnalyzeCli.ts index 83b2ae299ba..c999804abbd 100644 --- a/app-shell/src/protocol-analysis/executeAnalyzeCli.ts +++ b/app-shell/src/protocol-analysis/executeAnalyzeCli.ts @@ -25,6 +25,6 @@ export function executeAnalyzeCli( ? error.stderr : error.message - throw new Error(message) + throw new Error(message as string) }) } diff --git a/app-shell/src/protocol-analysis/index.ts b/app-shell/src/protocol-analysis/index.ts index 7264bb3819a..86d94636212 100644 --- a/app-shell/src/protocol-analysis/index.ts +++ b/app-shell/src/protocol-analysis/index.ts @@ -30,7 +30,7 @@ export function registerProtocolAnalysis( selectPythonPath(pathToPythonOverride) handleConfigChange(CONFIG_PYTHON_PATH_TO_PYTHON_OVERRIDE, newValue => { - selectPythonPath(newValue) + selectPythonPath(newValue as string | null) }) return function handleIncomingAction(action: Action): void { diff --git a/app-shell/src/protocol-storage/file-system.ts b/app-shell/src/protocol-storage/file-system.ts index 0dbbf290860..9afea8a83aa 100644 --- a/app-shell/src/protocol-storage/file-system.ts +++ b/app-shell/src/protocol-storage/file-system.ts @@ -109,7 +109,7 @@ export function addProtocolFile( protocolsDirPath: string ): Promise { const protocolKey = uuid() - const protocolDirPath = path.join(protocolsDirPath, protocolKey) + const protocolDirPath = path.join(protocolsDirPath, protocolKey as string) const srcDirPath = path.join(protocolDirPath, PROTOCOL_SRC_DIRECTORY_NAME) const analysisDirPath = path.join( diff --git a/app-shell/src/usb.ts b/app-shell/src/usb.ts index 370051829d9..276c537f062 100644 --- a/app-shell/src/usb.ts +++ b/app-shell/src/usb.ts @@ -105,7 +105,9 @@ async function usbListener( // check for formDataProxy if (data?.proxiedFormData != null) { // reconstruct FormData - const formData = reconstructFormData(data.proxiedFormData) + const formData = reconstructFormData( + data.proxiedFormData as IPCSafeFormData + ) formHeaders = formData.getHeaders() data = formData } @@ -166,7 +168,7 @@ function tryCreateAndStartUsbHttpRequests(dispatch: Dispatch): void { const message = err?.message ?? err usbLog.error(`Failed to create serial port: ${message}`) } - if (agent) { + if (agent != null) { ipcMain.removeHandler('usb:request') ipcMain.handle('usb:request', usbListener) dispatch(usbRequestsStart()) diff --git a/app/src/App/DesktopAppFallback.tsx b/app/src/App/DesktopAppFallback.tsx index 6b8a73cca1d..beca77227ca 100644 --- a/app/src/App/DesktopAppFallback.tsx +++ b/app/src/App/DesktopAppFallback.tsx @@ -34,7 +34,7 @@ export function DesktopAppFallback({ error }: FallbackProps): JSX.Element { }) // route to the root page and initiate an electron browser window reload via app-shell history.push('/') - dispatch(reloadUi(error.message)) + dispatch(reloadUi(error.message as string)) } return ( diff --git a/app/src/App/OnDeviceDisplayAppFallback.tsx b/app/src/App/OnDeviceDisplayAppFallback.tsx index 0e48a31e565..5c9735fb736 100644 --- a/app/src/App/OnDeviceDisplayAppFallback.tsx +++ b/app/src/App/OnDeviceDisplayAppFallback.tsx @@ -38,7 +38,7 @@ export function OnDeviceDisplayAppFallback({ name: ANALYTICS_ODD_APP_ERROR, properties: { errorMessage: error.message, robotSerialNumber }, }) - dispatch(appRestart(error.message)) + dispatch(appRestart(error.message as string)) } const modalHeader: ModalHeaderBaseProps = { title: t('error_boundary_title'), diff --git a/app/src/App/hooks.ts b/app/src/App/hooks.ts index 6519f5dac3a..7e5054c8ae8 100644 --- a/app/src/App/hooks.ts +++ b/app/src/App/hooks.ts @@ -90,7 +90,7 @@ export function useProtocolReceiptToast(): void { makeToast( t('protocol_added', { protocol_name: truncateString(name, 30), - }), + }) as string, 'success', { closeButton: true, diff --git a/app/src/i18n.ts b/app/src/i18n.ts index 38bb6803b45..0a9701a8e87 100644 --- a/app/src/i18n.ts +++ b/app/src/i18n.ts @@ -15,7 +15,7 @@ const i18nConfig: InitOptions = { defaultNS: 'shared', interpolation: { escapeValue: false, // not needed for react as it escapes by default - format: function (value, format, lng) { + format: function (value: string, format, lng) { if (format === 'upperCase') return value.toUpperCase() if (format === 'lowerCase') return value.toLowerCase() if (format === 'capitalize') return capitalize(value) diff --git a/app/src/molecules/Command/CommandText.tsx b/app/src/molecules/Command/CommandText.tsx index 071dfd0dea7..ffa00656aee 100644 --- a/app/src/molecules/Command/CommandText.tsx +++ b/app/src/molecules/Command/CommandText.tsx @@ -24,6 +24,7 @@ import { MoveLabwareCommandText } from './MoveLabwareCommandText' import type { RobotType, RunTimeCommand } from '@opentrons/shared-data' import type { StyleProps } from '@opentrons/components' import type { CommandTextData } from './types' +import type { TFunction } from 'i18next' const SIMPLE_TRANSLATION_KEY_BY_COMMAND_TYPE: { [commandType in RunTimeCommand['commandType']]?: string @@ -114,7 +115,7 @@ export function CommandText(props: Props): JSX.Element | null { const steps = profile.map( ({ holdSeconds, celsius }: { holdSeconds: number; celsius: number }) => t('tc_run_profile_steps', { - celsius: celsius, + celsius, seconds: holdSeconds, }).trim() ) @@ -217,7 +218,7 @@ export function CommandText(props: Props): JSX.Element | null { ? getLabwareDisplayLocation( commandTextData, labwareLocation, - t, + t as TFunction, robotType ) : '' @@ -298,7 +299,7 @@ export function CommandText(props: Props): JSX.Element | null { const addressableAreaDisplayName = getAddressableAreaDisplayName( commandTextData, command.id, - t + t as TFunction ) return ( @@ -313,7 +314,7 @@ export function CommandText(props: Props): JSX.Element | null { const addressableAreaDisplayName = getAddressableAreaDisplayName( commandTextData, command.id, - t + t as TFunction ) return ( @@ -361,7 +362,7 @@ export function CommandText(props: Props): JSX.Element | null { case 'waitForResume': { return ( - {command.params?.message && command.params.message !== '' + {command.params?.message != null && command.params.message !== '' ? command.params.message : t('wait_for_resume')} @@ -373,7 +374,7 @@ export function CommandText(props: Props): JSX.Element | null { if ('waitForResume' in command.params) { return ( - {command.params?.message && command.params.message !== '' + {command.params?.message != null && command.params.message !== '' ? command.params.message : t('wait_for_resume')} diff --git a/app/src/molecules/Command/MoveLabwareCommandText.tsx b/app/src/molecules/Command/MoveLabwareCommandText.tsx index 4296b3a2aa1..030177fddfc 100644 --- a/app/src/molecules/Command/MoveLabwareCommandText.tsx +++ b/app/src/molecules/Command/MoveLabwareCommandText.tsx @@ -8,6 +8,7 @@ import type { RobotType, } from '@opentrons/shared-data' import type { CommandTextData } from './types' +import type { TFunction } from 'i18next' interface MoveLabwareCommandTextProps { command: MoveLabwareRunTimeCommand @@ -29,7 +30,7 @@ export function MoveLabwareCommandText( const newDisplayLocation = getLabwareDisplayLocation( commandTextData, newLocation, - t, + t as TFunction, robotType ) @@ -47,7 +48,7 @@ export function MoveLabwareCommandText( ? getLabwareDisplayLocation( commandTextData, oldLocation, - t, + t as TFunction, robotType ) : '', @@ -60,7 +61,7 @@ export function MoveLabwareCommandText( ? getLabwareDisplayLocation( commandTextData, oldLocation, - t, + t as TFunction, robotType ) : '', diff --git a/app/src/molecules/Command/PipettingCommandText.tsx b/app/src/molecules/Command/PipettingCommandText.tsx index b2b82123305..3037ce3e2c3 100644 --- a/app/src/molecules/Command/PipettingCommandText.tsx +++ b/app/src/molecules/Command/PipettingCommandText.tsx @@ -16,6 +16,7 @@ import type { RobotType, } from '@opentrons/shared-data' import type { CommandTextData } from './types' +import type { TFunction } from 'i18next' interface PipettingCommandTextProps { command: PipettingRunTimeCommand @@ -47,7 +48,7 @@ export const PipettingCommandText = ({ ? getLabwareDisplayLocation( commandTextData, labwareLocation, - t, + t as TFunction, robotType ) : '' @@ -58,18 +59,18 @@ export const PipettingCommandText = ({ well_name: wellName, labware: getLabwareName(commandTextData, labwareId), labware_location: displayLocation, - volume: volume, + volume, flow_rate: flowRate, }) } case 'dispense': { const { volume, flowRate, pushOut } = command.params - return pushOut + return pushOut != null ? t('dispense_push_out', { well_name: wellName, labware: getLabwareName(commandTextData, labwareId), labware_location: displayLocation, - volume: volume, + volume, flow_rate: flowRate, push_out_volume: pushOut, }) @@ -77,7 +78,7 @@ export const PipettingCommandText = ({ well_name: wellName, labware: getLabwareName(commandTextData, labwareId), labware_location: displayLocation, - volume: volume, + volume, flow_rate: flowRate, }) } @@ -98,7 +99,7 @@ export const PipettingCommandText = ({ const labwareDef = labwareDefinitions.find( lw => getLabwareDefURI(lw) === loadedLabware?.definitionUri ) - return labwareDef?.parameters.isTiprack + return Boolean(labwareDef?.parameters.isTiprack) ? t('return_tip', { well_name: wellName, labware: getLabwareName(commandTextData, labwareId), @@ -133,7 +134,7 @@ export const PipettingCommandText = ({ } case 'dispenseInPlace': { const { volume, flowRate } = command.params - return t('dispense_in_place', { volume: volume, flow_rate: flowRate }) + return t('dispense_in_place', { volume, flow_rate: flowRate }) } case 'blowOutInPlace': { const { flowRate } = command.params diff --git a/app/src/molecules/GenericWizardTile/GenericWizardTile.stories.tsx b/app/src/molecules/GenericWizardTile/GenericWizardTile.stories.tsx index 3eebb98ed3c..cefbfc7d65e 100644 --- a/app/src/molecules/GenericWizardTile/GenericWizardTile.stories.tsx +++ b/app/src/molecules/GenericWizardTile/GenericWizardTile.stories.tsx @@ -14,7 +14,7 @@ import { WizardHeader } from '../WizardHeader' import { configReducer } from '../../redux/config/reducer' import { GenericWizardTile } from './index' -import type { Store } from 'redux' +import type { Store, StoreEnhancer } from 'redux' import type { Story, Meta } from '@storybook/react' const dummyConfig = { @@ -23,7 +23,10 @@ const dummyConfig = { }, } as any -const store: Store = createStore(configReducer, dummyConfig) +const store: Store = createStore( + configReducer, + dummyConfig as StoreEnhancer +) export default { title: 'App/Molecules/GenericWizardTile', diff --git a/app/src/molecules/InterventionModal/InterventionModal.stories.tsx b/app/src/molecules/InterventionModal/InterventionModal.stories.tsx index 5cf157ee8c2..5dbeda42a77 100644 --- a/app/src/molecules/InterventionModal/InterventionModal.stories.tsx +++ b/app/src/molecules/InterventionModal/InterventionModal.stories.tsx @@ -6,7 +6,7 @@ import { StyledText } from '@opentrons/components' import { configReducer } from '../../redux/config/reducer' import { InterventionModal as InterventionModalComponent } from './' -import type { Store } from 'redux' +import type { Store, StoreEnhancer } from 'redux' import type { Meta, StoryObj } from '@storybook/react' const dummyConfig = { @@ -14,7 +14,10 @@ const dummyConfig = { isOnDevice: false, }, } as any -const store: Store = createStore(configReducer, dummyConfig) +const store: Store = createStore( + configReducer, + dummyConfig as StoreEnhancer +) const meta: Meta = { title: 'App/Molecules/InterventionModal', diff --git a/app/src/molecules/SimpleWizardBody/SimpleWizardBody.stories.tsx b/app/src/molecules/SimpleWizardBody/SimpleWizardBody.stories.tsx index 8e1faf9ecc7..ef58f6f61d0 100644 --- a/app/src/molecules/SimpleWizardBody/SimpleWizardBody.stories.tsx +++ b/app/src/molecules/SimpleWizardBody/SimpleWizardBody.stories.tsx @@ -7,7 +7,7 @@ import { WizardHeader } from '../WizardHeader' import { configReducer } from '../../redux/config/reducer' import { SimpleWizardBody } from './index' -import type { Store } from 'redux' +import type { Store, StoreEnhancer } from 'redux' import type { Story, Meta } from '@storybook/react' export default { @@ -21,7 +21,10 @@ const dummyConfig = { }, } as any -const store: Store = createStore(configReducer, dummyConfig) +const store: Store = createStore( + configReducer, + dummyConfig as StoreEnhancer +) const Template: Story> = args => ( diff --git a/app/src/organisms/AdvancedSettings/ClearUnavailableRobots.tsx b/app/src/organisms/AdvancedSettings/ClearUnavailableRobots.tsx index 58872a6c497..7d6cd8176e3 100644 --- a/app/src/organisms/AdvancedSettings/ClearUnavailableRobots.tsx +++ b/app/src/organisms/AdvancedSettings/ClearUnavailableRobots.tsx @@ -51,9 +51,12 @@ export function ClearUnavailableRobots(): JSX.Element { const handleDeleteUnavailRobots = (): void => { if (isUnavailableRobots) { dispatch(clearDiscoveryCache()) - makeToast(t('successfully_deleted_unavail_robots'), SUCCESS_TOAST) + makeToast( + t('successfully_deleted_unavail_robots') as string, + SUCCESS_TOAST + ) } else { - makeToast(t('no_unavail_robots_to_clear'), ERROR_TOAST) + makeToast(t('no_unavail_robots_to_clear') as string, ERROR_TOAST) } } const { diff --git a/app/src/organisms/Alerts/AlertsModal.tsx b/app/src/organisms/Alerts/AlertsModal.tsx index 89815fa4b26..af2c46e9aaf 100644 --- a/app/src/organisms/Alerts/AlertsModal.tsx +++ b/app/src/organisms/Alerts/AlertsModal.tsx @@ -55,7 +55,7 @@ export function AlertsModal({ toastIdRef }: AlertsModalProps): JSX.Element { React.useEffect(() => { if (hasJustUpdated) { makeToast( - t('branded:opentrons_app_successfully_updated'), + t('branded:opentrons_app_successfully_updated') as string, SUCCESS_TOAST, { closeButton: true, @@ -69,7 +69,7 @@ export function AlertsModal({ toastIdRef }: AlertsModalProps): JSX.Element { React.useEffect(() => { if (createAppUpdateAvailableToast) { toastIdRef.current = makeToast( - t('branded:opentrons_app_update_available_variation'), + t('branded:opentrons_app_update_available_variation') as string, WARNING_TOAST, { closeButton: true, diff --git a/app/src/organisms/AppSettings/ConnectRobotSlideout.tsx b/app/src/organisms/AppSettings/ConnectRobotSlideout.tsx index 1935cd33d78..f98609283d6 100644 --- a/app/src/organisms/AppSettings/ConnectRobotSlideout.tsx +++ b/app/src/organisms/AppSettings/ConnectRobotSlideout.tsx @@ -123,10 +123,10 @@ export function ConnectRobotSlideout({ > {t('discovery_timeout')} - {displayLinkButton(t('shared:try_again'))} + {displayLinkButton(t('shared:try_again') as string)} ) : ( - displayLinkButton(t('shared:refresh')) + displayLinkButton(t('shared:refresh') as string) ), ] )} diff --git a/app/src/organisms/ApplyHistoricOffsets/LabwareOffsetTable.tsx b/app/src/organisms/ApplyHistoricOffsets/LabwareOffsetTable.tsx index b9248b6de92..b14075a904a 100644 --- a/app/src/organisms/ApplyHistoricOffsets/LabwareOffsetTable.tsx +++ b/app/src/organisms/ApplyHistoricOffsets/LabwareOffsetTable.tsx @@ -7,6 +7,7 @@ import { formatTimestamp } from '../Devices/utils' import { getDisplayLocation } from '../LabwarePositionCheck/utils/getDisplayLocation' import type { LabwareDefinition2 } from '@opentrons/shared-data' import type { OffsetCandidate } from './hooks/useOffsetCandidatesForAnalysis' +import type { TFunction } from 'i18next' const OffsetTable = styled('table')` ${TYPOGRAPHY.labelRegular} @@ -55,7 +56,12 @@ export function LabwareOffsetTable( {offsetCandidates.map(offset => ( - {getDisplayLocation(offset.location, labwareDefinitions, t, i18n)} + {getDisplayLocation( + offset.location, + labwareDefinitions, + t as TFunction, + i18n + )} {formatTimestamp(offset.runCreatedAt)} diff --git a/app/src/organisms/ChooseProtocolSlideout/index.tsx b/app/src/organisms/ChooseProtocolSlideout/index.tsx index ed8841ad7b9..6e3a2a1d9d9 100644 --- a/app/src/organisms/ChooseProtocolSlideout/index.tsx +++ b/app/src/organisms/ChooseProtocolSlideout/index.tsx @@ -275,7 +275,7 @@ export function ChooseProtocolSlideoutComponent( }) : null if (error != null) { - errors.push(error) + errors.push(error as string) } return ( - {runtimeParam.value + {Boolean(runtimeParam.value) ? t('protocol_details:on') : t('protocol_details:off')} @@ -384,7 +384,7 @@ export function ChooseProtocolSlideoutComponent( ? null : t('protocol_details:csv_file_type_required') if (error != null) { - errors.push(error) + errors.push(error as string) } return !enableCsvFile ? null : ( - {runtimeParam.value ? t('on') : t('off')} + {Boolean(runtimeParam.value) ? t('on') : t('off')} @@ -530,7 +530,7 @@ export function ChooseRobotSlideout( ? null : t('csv_file_type_required') if (error != null) { - errors.push(error) + errors.push(error as string) } return !enableCsvFile ? null : ( diff --git a/app/src/organisms/Devices/ProtocolRun/SetupLiquids/index.tsx b/app/src/organisms/Devices/ProtocolRun/SetupLiquids/index.tsx index bb4de2d50ea..ed563673775 100644 --- a/app/src/organisms/Devices/ProtocolRun/SetupLiquids/index.tsx +++ b/app/src/organisms/Devices/ProtocolRun/SetupLiquids/index.tsx @@ -33,8 +33,8 @@ export function SetupLiquids({ }: SetupLiquidsProps): JSX.Element { const { t } = useTranslation('protocol_setup') const [selectedValue, toggleGroup] = useToggleGroup( - t('list_view'), - t('map_view'), + t('list_view') as string, + t('map_view') as string, ANALYTICS_LIQUID_SETUP_VIEW_TOGGLE ) return ( diff --git a/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/index.tsx b/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/index.tsx index 33451516e41..c3cd7dbcf3e 100644 --- a/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/index.tsx +++ b/app/src/organisms/Devices/ProtocolRun/SetupModuleAndDeck/index.tsx @@ -52,8 +52,8 @@ export const SetupModuleAndDeck = ({ }: SetupModuleAndDeckProps): JSX.Element => { const { t, i18n } = useTranslation('protocol_setup') const [selectedValue, toggleGroup] = useToggleGroup( - t('list_view'), - t('map_view') + t('list_view') as string, + t('map_view') as string ) const robotType = useRobotType(robotName) diff --git a/app/src/organisms/Devices/RobotSettings/AdvancedTab/Troubleshooting.tsx b/app/src/organisms/Devices/RobotSettings/AdvancedTab/Troubleshooting.tsx index 0eafea22b18..c54959f5d68 100644 --- a/app/src/organisms/Devices/RobotSettings/AdvancedTab/Troubleshooting.tsx +++ b/app/src/organisms/Devices/RobotSettings/AdvancedTab/Troubleshooting.tsx @@ -35,7 +35,7 @@ export function Troubleshooting({ const { t } = useTranslation('device_settings') const robot = useRobot(robotName) const controlDisabled = robot?.status !== CONNECTABLE - const logsAvailable = robot?.health != null && robot.health.logs != null + const logsAvailable = robot?.health?.logs != null const [ isDownloadingRobotLogs, setIsDownloadingRobotLogs, @@ -47,7 +47,7 @@ export function Troubleshooting({ const handleClick: React.MouseEventHandler = () => { setIsDownloadingRobotLogs(true) - const toastId = makeToast(t('downloading_logs'), INFO_TOAST, { + const toastId = makeToast(t('downloading_logs') as string, INFO_TOAST, { disableTimeout: true, icon: toastIcon, }) diff --git a/app/src/organisms/Devices/hooks/useDownloadRunLog.ts b/app/src/organisms/Devices/hooks/useDownloadRunLog.ts index 76d76f04dce..4812474b5e1 100644 --- a/app/src/organisms/Devices/hooks/useDownloadRunLog.ts +++ b/app/src/organisms/Devices/hooks/useDownloadRunLog.ts @@ -6,7 +6,6 @@ import { ERROR_TOAST, INFO_TOAST } from '../../../atoms/Toast' import { useToaster } from '../../../organisms/ToasterOven' import { downloadFile } from '../utils' import type { IconProps } from '@opentrons/components' -import type { HostConfig } from '@opentrons/api-client' export function useDownloadRunLog( robotName: string, @@ -22,24 +21,24 @@ export function useDownloadRunLog( const downloadRunLog = (): void => { setIsLoading(true) - makeToast(t('downloading_run_log'), INFO_TOAST, { + makeToast(t('downloading_run_log') as string, INFO_TOAST, { icon: toastIcon, }) - + if (host == null) return // first getCommands to get total length of commands - getCommands(host as HostConfig, runId as string, { + getCommands(host, runId, { cursor: null, pageLength: 0, }) .then(response => { const { totalLength } = response.data.meta - getCommands(host as HostConfig, runId as string, { + getCommands(host, runId, { cursor: 0, pageLength: totalLength, }) .then(response => { const commands = response.data - getRun(host as HostConfig, runId as string) + getRun(host, runId) .then(response => { const runRecord = response.data const runDetails = { @@ -55,7 +54,7 @@ export function useDownloadRunLog( }_${createdAt}.json` if (protocolId != null) { - getProtocol(host as HostConfig, protocolId) + getProtocol(host, protocolId) .then(response => { const protocolName = response.data.data.metadata.protocolName diff --git a/app/src/organisms/Devices/hooks/useProtocolRunAnalyticsData.ts b/app/src/organisms/Devices/hooks/useProtocolRunAnalyticsData.ts index 5cf38a7f0d6..47407f6c5e0 100644 --- a/app/src/organisms/Devices/hooks/useProtocolRunAnalyticsData.ts +++ b/app/src/organisms/Devices/hooks/useProtocolRunAnalyticsData.ts @@ -22,7 +22,7 @@ export const parseProtocolRunAnalyticsData = ( robot: DiscoveredRobot | null ) => () => { const hashTasks = [ - hash(protocolAnalysis?.metadata?.author) ?? '', + hash(protocolAnalysis?.metadata?.author as string) ?? '', hash(storedProtocol?.srcFiles?.toString() ?? '') ?? '', ] @@ -94,7 +94,10 @@ export function useProtocolRunAnalyticsData( ) const storedProtocolAnalysis = useStoredProtocolAnalysis(runId) const storedProtocol = useSelector((state: State) => - getStoredProtocol(state, storedProtocolAnalysis?.metadata?.protocolKey) + getStoredProtocol( + state, + storedProtocolAnalysis?.metadata?.protocolKey as string | undefined + ) ) const protocolAnalysis = robotProtocolAnalysis != null && robotProtocolMetadata != null diff --git a/app/src/organisms/EmergencyStop/DesktopEstopMissingModal.stories.tsx b/app/src/organisms/EmergencyStop/DesktopEstopMissingModal.stories.tsx index def8817e5dd..324ca64efc4 100644 --- a/app/src/organisms/EmergencyStop/DesktopEstopMissingModal.stories.tsx +++ b/app/src/organisms/EmergencyStop/DesktopEstopMissingModal.stories.tsx @@ -5,7 +5,7 @@ import { createStore } from 'redux' import { configReducer } from '../../redux/config/reducer' import { EstopMissingModal } from '.' -import type { Store } from 'redux' +import type { Store, StoreEnhancer } from 'redux' import type { Story, Meta } from '@storybook/react' export default { @@ -19,7 +19,10 @@ const dummyConfig = { }, } as any -const store: Store = createStore(configReducer, dummyConfig) +const store: Store = createStore( + configReducer, + dummyConfig as StoreEnhancer +) const Template: Story< React.ComponentProps diff --git a/app/src/organisms/EmergencyStop/DesktopEstopPressedModal.stories.tsx b/app/src/organisms/EmergencyStop/DesktopEstopPressedModal.stories.tsx index 5a0161adf42..66c49a944a5 100644 --- a/app/src/organisms/EmergencyStop/DesktopEstopPressedModal.stories.tsx +++ b/app/src/organisms/EmergencyStop/DesktopEstopPressedModal.stories.tsx @@ -6,7 +6,7 @@ import { QueryClient, QueryClientProvider } from 'react-query' import { configReducer } from '../../redux/config/reducer' import { EstopPressedModal } from '.' -import type { Store } from 'redux' +import type { Store, StoreEnhancer } from 'redux' import type { Story, Meta } from '@storybook/react' export default { @@ -20,7 +20,10 @@ const dummyConfig = { }, } as any -const store: Store = createStore(configReducer, dummyConfig) +const store: Store = createStore( + configReducer, + dummyConfig as StoreEnhancer +) const queryClient = new QueryClient() const Template: Story< diff --git a/app/src/organisms/EmergencyStop/TouchscreenEstopMissingModal.stories.tsx b/app/src/organisms/EmergencyStop/TouchscreenEstopMissingModal.stories.tsx index f2bb0cf2e7f..4c91bc65464 100644 --- a/app/src/organisms/EmergencyStop/TouchscreenEstopMissingModal.stories.tsx +++ b/app/src/organisms/EmergencyStop/TouchscreenEstopMissingModal.stories.tsx @@ -7,7 +7,7 @@ import { VIEWPORT } from '@opentrons/components' import { configReducer } from '../../redux/config/reducer' import { EstopMissingModal } from '.' -import type { Store } from 'redux' +import type { Store, StoreEnhancer } from 'redux' import type { Story, Meta } from '@storybook/react' export default { @@ -22,7 +22,10 @@ const dummyConfig = { }, } as any -const store: Store = createStore(configReducer, dummyConfig) +const store: Store = createStore( + configReducer, + dummyConfig as StoreEnhancer +) const Template: Story< React.ComponentProps diff --git a/app/src/organisms/EmergencyStop/TouchscreenEstopPressedModal.stories.tsx b/app/src/organisms/EmergencyStop/TouchscreenEstopPressedModal.stories.tsx index 7ea8618203d..b78864b74ff 100644 --- a/app/src/organisms/EmergencyStop/TouchscreenEstopPressedModal.stories.tsx +++ b/app/src/organisms/EmergencyStop/TouchscreenEstopPressedModal.stories.tsx @@ -8,7 +8,7 @@ import { VIEWPORT } from '@opentrons/components' import { configReducer } from '../../redux/config/reducer' import { EstopPressedModal } from '.' -import type { Store } from 'redux' +import type { Store, StoreEnhancer } from 'redux' import type { Story, Meta } from '@storybook/react' export default { @@ -23,7 +23,10 @@ const dummyConfig = { }, } as any -const store: Store = createStore(configReducer, dummyConfig) +const store: Store = createStore( + configReducer, + dummyConfig as StoreEnhancer +) const queryClient = new QueryClient() const Template: Story< diff --git a/app/src/organisms/GripperWizardFlows/BeforeBeginning.tsx b/app/src/organisms/GripperWizardFlows/BeforeBeginning.tsx index 2b2b2ed789d..49eec44755e 100644 --- a/app/src/organisms/GripperWizardFlows/BeforeBeginning.tsx +++ b/app/src/organisms/GripperWizardFlows/BeforeBeginning.tsx @@ -96,7 +96,7 @@ export const BeforeBeginning = ( proceed() }) .catch(error => { - setErrorMessage(error.message) + setErrorMessage(error.message as string) }) } diff --git a/app/src/organisms/GripperWizardFlows/GripperWizardFlows.stories.tsx b/app/src/organisms/GripperWizardFlows/GripperWizardFlows.stories.tsx index 908d31b8fc5..86a7ebdf427 100644 --- a/app/src/organisms/GripperWizardFlows/GripperWizardFlows.stories.tsx +++ b/app/src/organisms/GripperWizardFlows/GripperWizardFlows.stories.tsx @@ -11,7 +11,7 @@ import { import { configReducer } from '../../redux/config/reducer' import { GripperWizardFlows } from './' -import type { Store } from 'redux' +import type { Store, StoreEnhancer } from 'redux' import type { Story, Meta } from '@storybook/react' export default { @@ -45,7 +45,10 @@ const dummyConfig = { }, } as any -const store: Store = createStore(configReducer, dummyConfig) +const store: Store = createStore( + configReducer, + dummyConfig as StoreEnhancer +) const queryClient = new QueryClient() const Template: Story< diff --git a/app/src/organisms/GripperWizardFlows/MovePin.tsx b/app/src/organisms/GripperWizardFlows/MovePin.tsx index cbee97f6d67..eaaf8ae9332 100644 --- a/app/src/organisms/GripperWizardFlows/MovePin.tsx +++ b/app/src/organisms/GripperWizardFlows/MovePin.tsx @@ -96,7 +96,7 @@ export const MovePin = (props: MovePinProps): JSX.Element | null => { setErrorMessage(data.error?.detail ?? null) } if (jaw === 'front' && data?.result?.jawOffset != null) { - setFrontJawOffset(data.result.jawOffset) + setFrontJawOffset(data.result.jawOffset as Coordinates) } createRunCommand({ maintenanceRunId, @@ -115,19 +115,19 @@ export const MovePin = (props: MovePinProps): JSX.Element | null => { proceed() }) .catch(error => { - setErrorMessage(error.message) + setErrorMessage(error.message as string) }) }) .catch(error => { - setErrorMessage(error.message) + setErrorMessage(error.message as string) }) }) .catch(error => { - setErrorMessage(error.message) + setErrorMessage(error.message as string) }) }) .catch(error => { - setErrorMessage(error.message) + setErrorMessage(error.message as string) }) } } diff --git a/app/src/organisms/GripperWizardFlows/index.tsx b/app/src/organisms/GripperWizardFlows/index.tsx index bbf4ad90f0a..aafc36acf9e 100644 --- a/app/src/organisms/GripperWizardFlows/index.tsx +++ b/app/src/organisms/GripperWizardFlows/index.tsx @@ -150,7 +150,7 @@ export function GripperWizardFlows( }) .catch(error => { setIsExiting(true) - setErrorMessage(error.message) + setErrorMessage(error.message as string) }) } } diff --git a/app/src/organisms/IncompatibleModule/IncompatibleModuleODDModalBody.tsx b/app/src/organisms/IncompatibleModule/IncompatibleModuleODDModalBody.tsx index fb4981c0c71..f1be6b125b5 100644 --- a/app/src/organisms/IncompatibleModule/IncompatibleModuleODDModalBody.tsx +++ b/app/src/organisms/IncompatibleModule/IncompatibleModuleODDModalBody.tsx @@ -23,7 +23,7 @@ export function IncompatibleModuleODDModalBody({ }: IncompatibleModuleODDModalBodyProps): JSX.Element { const { t } = useTranslation('incompatible_modules') const incompatibleModuleHeader: ModalHeaderBaseProps = { - title: capitalize(t('incompatible_modules_attached')), + title: capitalize(t('incompatible_modules_attached') as string), } return ( diff --git a/app/src/organisms/InterventionModal/InterventionModal.stories.tsx b/app/src/organisms/InterventionModal/InterventionModal.stories.tsx index da38efd7a4a..a7bbfddab3c 100644 --- a/app/src/organisms/InterventionModal/InterventionModal.stories.tsx +++ b/app/src/organisms/InterventionModal/InterventionModal.stories.tsx @@ -15,7 +15,7 @@ import { } from '../../redux/discovery/constants' import { InterventionModal as InterventionModalComponent } from './' -import type { Store } from 'redux' +import type { Store, StoreEnhancer } from 'redux' import type { Story, Meta } from '@storybook/react' const dummyConfig = { @@ -44,7 +44,10 @@ const dummyConfig = { }, } as any -const store: Store = createStore(configReducer, dummyConfig) +const store: Store = createStore( + configReducer, + dummyConfig as StoreEnhancer +) const queryClient = new QueryClient() const now = new Date() diff --git a/app/src/organisms/LabwarePositionCheck/AttachProbe.tsx b/app/src/organisms/LabwarePositionCheck/AttachProbe.tsx index b995ae9eeee..f84c0da7e10 100644 --- a/app/src/organisms/LabwarePositionCheck/AttachProbe.tsx +++ b/app/src/organisms/LabwarePositionCheck/AttachProbe.tsx @@ -85,7 +85,7 @@ export const AttachProbe = (props: AttachProbeProps): JSX.Element | null => { ], false ).catch(error => { - setFatalError(error.message) + setFatalError(error.message as string) }) }, []) @@ -99,7 +99,7 @@ export const AttachProbe = (props: AttachProbeProps): JSX.Element | null => { { commandType: 'verifyTipPresence', params: { - pipetteId: pipetteId, + pipetteId, expectedState: 'present', followSingularSensor: 'primary', }, diff --git a/app/src/organisms/LabwarePositionCheck/CheckItem.tsx b/app/src/organisms/LabwarePositionCheck/CheckItem.tsx index 9cb13b0d473..00a2d181cdf 100644 --- a/app/src/organisms/LabwarePositionCheck/CheckItem.tsx +++ b/app/src/organisms/LabwarePositionCheck/CheckItem.tsx @@ -44,6 +44,7 @@ import type { WorkingOffset, } from './types' import type { Jog } from '../../molecules/JogControls/types' +import type { TFunction } from 'i18next' const PROBE_LENGTH_MM = 44.5 @@ -149,7 +150,12 @@ export const CheckItem = (props: CheckItemProps): JSX.Element | null => { const pipetteZMotorAxis: 'leftZ' | 'rightZ' = pipetteMount === 'left' ? 'leftZ' : 'rightZ' const isTiprack = getIsTiprack(labwareDef) - const displayLocation = getDisplayLocation(location, labwareDefs, t, i18n) + const displayLocation = getDisplayLocation( + location, + labwareDefs, + t as TFunction, + i18n + ) const labwareDisplayName = getLabwareDisplayName(labwareDef) let placeItemInstruction: JSX.Element = ( @@ -189,7 +195,7 @@ export const CheckItem = (props: CheckItemProps): JSX.Element | null => { location: getDisplayLocation( omit(location, ['definitionUri']), // only want the adapter's location here labwareDefs, - t, + t as TFunction, i18n ), }} @@ -307,7 +313,7 @@ export const CheckItem = (props: CheckItemProps): JSX.Element | null => { { commandType: 'moveLabware' as const, params: { - labwareId: labwareId, + labwareId, newLocation: 'offDeck', strategy: 'manualMoveWithoutPause', }, @@ -325,7 +331,7 @@ export const CheckItem = (props: CheckItemProps): JSX.Element | null => { { commandType: 'moveLabware' as const, params: { - labwareId: labwareId, + labwareId, newLocation: 'offDeck', strategy: 'manualMoveWithoutPause', }, diff --git a/app/src/organisms/LabwarePositionCheck/DetachProbe.tsx b/app/src/organisms/LabwarePositionCheck/DetachProbe.tsx index 94ece095e3e..4e5a45a965b 100644 --- a/app/src/organisms/LabwarePositionCheck/DetachProbe.tsx +++ b/app/src/organisms/LabwarePositionCheck/DetachProbe.tsx @@ -71,7 +71,7 @@ export const DetachProbe = (props: DetachProbeProps): JSX.Element | null => { ], false ).catch(error => { - setFatalError(error.message) + setFatalError(error.message as string) }) }, []) diff --git a/app/src/organisms/LabwarePositionCheck/LabwarePositionCheckComponent.tsx b/app/src/organisms/LabwarePositionCheck/LabwarePositionCheckComponent.tsx index 0722465b50b..32662dd7391 100644 --- a/app/src/organisms/LabwarePositionCheck/LabwarePositionCheckComponent.tsx +++ b/app/src/organisms/LabwarePositionCheck/LabwarePositionCheckComponent.tsx @@ -279,13 +279,15 @@ export const LabwarePositionCheckComponent = ( maintenanceRunId, command: { commandType: 'moveRelative', - params: { pipetteId: pipetteId, distance: step * dir, axis }, + params: { pipetteId, distance: step * dir, axis }, }, waitUntilComplete: true, timeout: JOG_COMMAND_TIMEOUT, }) .then(data => { - onSuccess?.(data?.data?.result?.position ?? null) + onSuccess?.( + (data?.data?.result?.position ?? null) as Coordinates | null + ) }) .catch((e: Error) => { setFatalError(`error issuing jog command: ${e.message}`) diff --git a/app/src/organisms/LabwarePositionCheck/PickUpTip.tsx b/app/src/organisms/LabwarePositionCheck/PickUpTip.tsx index cf837cb1363..f7a0af90904 100644 --- a/app/src/organisms/LabwarePositionCheck/PickUpTip.tsx +++ b/app/src/organisms/LabwarePositionCheck/PickUpTip.tsx @@ -24,6 +24,8 @@ import { TipConfirmation } from './TipConfirmation' import { getLabwareDef } from './utils/labware' import { getLabwareDefinitionsFromCommands } from '../../molecules/Command/utils/getLabwareDefinitionsFromCommands' import { getDisplayLocation } from './utils/getDisplayLocation' +import { useSelector } from 'react-redux' +import { getIsOnDevice } from '../../redux/config' import type { CompletedProtocolAnalysis, @@ -39,8 +41,7 @@ import type { WorkingOffset, } from './types' import type { LabwareOffset } from '@opentrons/api-client' -import { useSelector } from 'react-redux' -import { getIsOnDevice } from '../../redux/config' +import type { TFunction } from 'i18next' interface PickUpTipProps extends PickUpTipStep { protocolData: CompletedProtocolAnalysis @@ -90,7 +91,7 @@ export const PickUpTip = (props: PickUpTipProps): JSX.Element | null => { const displayLocation = getDisplayLocation( location, getLabwareDefinitionsFromCommands(protocolData.commands), - t, + t as TFunction, i18n ) const labwareDisplayName = getLabwareDisplayName(labwareDef) @@ -178,8 +179,8 @@ export const PickUpTip = (props: PickUpTipProps): JSX.Element | null => { { commandType: 'moveToWell' as const, params: { - pipetteId: pipetteId, - labwareId: labwareId, + pipetteId, + labwareId, wellName: 'A1', wellLocation: { origin: 'top' as const }, }, @@ -266,7 +267,7 @@ export const PickUpTip = (props: PickUpTipProps): JSX.Element | null => { { commandType: 'moveLabware' as const, params: { - labwareId: labwareId, + labwareId, newLocation: 'offDeck', strategy: 'manualMoveWithoutPause', }, @@ -284,7 +285,7 @@ export const PickUpTip = (props: PickUpTipProps): JSX.Element | null => { { commandType: 'moveLabware' as const, params: { - labwareId: labwareId, + labwareId, newLocation: 'offDeck', strategy: 'manualMoveWithoutPause', }, @@ -335,8 +336,8 @@ export const PickUpTip = (props: PickUpTipProps): JSX.Element | null => { { commandType: 'moveToWell' as const, params: { - pipetteId: pipetteId, - labwareId: labwareId, + pipetteId, + labwareId, wellName: 'A1', wellLocation: { origin: 'top' as const }, }, @@ -364,7 +365,7 @@ export const PickUpTip = (props: PickUpTipProps): JSX.Element | null => { { commandType: 'moveLabware' as const, params: { - labwareId: labwareId, + labwareId, newLocation: 'offDeck', strategy: 'manualMoveWithoutPause', }, diff --git a/app/src/organisms/LabwarePositionCheck/ResultsSummary.tsx b/app/src/organisms/LabwarePositionCheck/ResultsSummary.tsx index 53d3d4400d8..235a395a03a 100644 --- a/app/src/organisms/LabwarePositionCheck/ResultsSummary.tsx +++ b/app/src/organisms/LabwarePositionCheck/ResultsSummary.tsx @@ -50,6 +50,7 @@ import type { LabwareOffsetCreateData, } from '@opentrons/api-client' import type { ResultsSummaryStep, WorkingOffset } from './types' +import type { TFunction } from 'i18next' const LPC_HELP_LINK_URL = 'https://support.opentrons.com/s/article/How-Labware-Offsets-work-on-the-OT-2' @@ -298,7 +299,12 @@ const OffsetTable = (props: OffsetTableProps): JSX.Element => { as="p" textTransform={TYPOGRAPHY.textTransformCapitalize} > - {getDisplayLocation(location, labwareDefinitions, t, i18n)} + {getDisplayLocation( + location, + labwareDefinitions, + t as TFunction, + i18n + )} diff --git a/app/src/organisms/LabwarePositionCheck/ReturnTip.tsx b/app/src/organisms/LabwarePositionCheck/ReturnTip.tsx index 642a88aacb6..2192562654c 100644 --- a/app/src/organisms/LabwarePositionCheck/ReturnTip.tsx +++ b/app/src/organisms/LabwarePositionCheck/ReturnTip.tsx @@ -30,6 +30,7 @@ import type { import type { VectorOffset } from '@opentrons/api-client' import type { useChainRunCommands } from '../../resources/runs' import type { ReturnTipStep } from './types' +import type { TFunction } from 'i18next' interface ReturnTipProps extends ReturnTipStep { protocolData: CompletedProtocolAnalysis @@ -63,7 +64,7 @@ export const ReturnTip = (props: ReturnTipProps): JSX.Element | null => { const displayLocation = getDisplayLocation( location, getLabwareDefinitionsFromCommands(protocolData.commands), - t, + t as TFunction, i18n ) const labwareDisplayName = getLabwareDisplayName(labwareDef) @@ -125,7 +126,7 @@ export const ReturnTip = (props: ReturnTipProps): JSX.Element | null => { { commandType: 'moveLabware' as const, params: { - labwareId: labwareId, + labwareId, newLocation: 'offDeck', strategy: 'manualMoveWithoutPause', }, @@ -143,7 +144,7 @@ export const ReturnTip = (props: ReturnTipProps): JSX.Element | null => { { commandType: 'moveLabware' as const, params: { - labwareId: labwareId, + labwareId, newLocation: 'offDeck', strategy: 'manualMoveWithoutPause', }, @@ -173,8 +174,8 @@ export const ReturnTip = (props: ReturnTipProps): JSX.Element | null => { { commandType: 'moveToWell' as const, params: { - pipetteId: pipetteId, - labwareId: labwareId, + pipetteId, + labwareId, wellName: 'A1', wellLocation: { origin: 'top' as const, @@ -185,8 +186,8 @@ export const ReturnTip = (props: ReturnTipProps): JSX.Element | null => { { commandType: 'dropTip' as const, params: { - pipetteId: pipetteId, - labwareId: labwareId, + pipetteId, + labwareId, wellName: 'A1', wellLocation: { origin: 'default' as const, diff --git a/app/src/organisms/ModuleCard/index.tsx b/app/src/organisms/ModuleCard/index.tsx index eac70fc4628..8ce69bc1728 100644 --- a/app/src/organisms/ModuleCard/index.tsx +++ b/app/src/organisms/ModuleCard/index.tsx @@ -140,9 +140,9 @@ export const ModuleCard = (props: ModuleCardProps): JSX.Element | null => { !MODULE_MODELS_OT2_ONLY.some(modModel => modModel === module.moduleModel) && module.moduleOffset?.last_modified == null const isPipetteReady = - (!attachPipetteRequired ?? false) && - (!calibratePipetteRequired ?? false) && - (!updatePipetteFWRequired ?? false) + !Boolean(attachPipetteRequired) && + !Boolean(calibratePipetteRequired) && + !Boolean(updatePipetteFWRequired) const latestRequest = useSelector(state => latestRequestId != null ? getRequestById(state, latestRequestId) : null @@ -153,12 +153,12 @@ export const ModuleCard = (props: ModuleCardProps): JSX.Element | null => { const [showFirmwareToast, setShowFirmwareToast] = React.useState(hasUpdated) const { makeToast } = useToaster() if (showFirmwareToast) { - makeToast(t('firmware_updated_successfully'), SUCCESS_TOAST) + makeToast(t('firmware_updated_successfully') as string, SUCCESS_TOAST) setShowFirmwareToast(false) } const handleFirmwareUpdateClick = (): void => { - robotName && handleModuleApiRequests(robotName, module.serialNumber) + robotName != null && handleModuleApiRequests(robotName, module.serialNumber) } const isEstopNotDisengaged = useIsEstopNotDisengaged(robotName) diff --git a/app/src/organisms/PipetteWizardFlows/AttachProbe.tsx b/app/src/organisms/PipetteWizardFlows/AttachProbe.tsx index ded4afcb7a7..d9b4e8baa49 100644 --- a/app/src/organisms/PipetteWizardFlows/AttachProbe.tsx +++ b/app/src/organisms/PipetteWizardFlows/AttachProbe.tsx @@ -77,7 +77,7 @@ export const AttachProbe = (props: AttachProbeProps): JSX.Element | null => { { commandType: 'verifyTipPresence', params: { - pipetteId: pipetteId, + pipetteId, expectedState: 'present', followSingularSensor: 'primary', }, @@ -87,7 +87,7 @@ export const AttachProbe = (props: AttachProbeProps): JSX.Element | null => { { commandType: 'home' as const, params: { - axes: axes, + axes, }, }, { @@ -99,13 +99,13 @@ export const AttachProbe = (props: AttachProbeProps): JSX.Element | null => { { commandType: 'calibration/calibratePipette' as const, params: { - mount: mount, + mount, }, }, { commandType: 'calibration/moveToMaintenancePosition' as const, params: { - mount: mount, + mount, }, }, ] @@ -116,7 +116,7 @@ export const AttachProbe = (props: AttachProbeProps): JSX.Element | null => { proceed() }) .catch(error => { - setShowErrorMessage(error.message) + setShowErrorMessage(error.message as string) }) }) .catch((e: Error) => { @@ -167,7 +167,7 @@ export const AttachProbe = (props: AttachProbeProps): JSX.Element | null => { } > {isExiting ? undefined : ( - + {t('calibration_probe_touching', { slotNumber: calSlotNum })} @@ -224,11 +224,13 @@ export const AttachProbe = (props: AttachProbeProps): JSX.Element | null => { {is96Channel && ( - {isWasteChuteOnDeck + {Boolean(isWasteChuteOnDeck) ? t('waste_chute_error') : t('waste_chute_warning')} diff --git a/app/src/organisms/PipetteWizardFlows/BeforeBeginning.tsx b/app/src/organisms/PipetteWizardFlows/BeforeBeginning.tsx index 3861bde63a7..078105259ad 100644 --- a/app/src/organisms/PipetteWizardFlows/BeforeBeginning.tsx +++ b/app/src/organisms/PipetteWizardFlows/BeforeBeginning.tsx @@ -144,14 +144,14 @@ export const BeforeBeginning = ( if (requiredPipette.pipetteName === 'p1000_96') { equipmentList = [ - { ...NINETY_SIX_CHANNEL_PIPETTE, displayName: displayName }, + { ...NINETY_SIX_CHANNEL_PIPETTE, displayName }, CALIBRATION_PROBE, HEX_SCREWDRIVER, NINETY_SIX_CHANNEL_MOUNTING_PLATE, ] } else { equipmentList = [ - { ...PIPETTE, displayName: displayName }, + { ...PIPETTE, displayName }, CALIBRATION_PROBE, HEX_SCREWDRIVER, ] @@ -174,14 +174,14 @@ export const BeforeBeginning = ( params: { pipetteName: attachedPipettes[mount]?.instrumentName ?? '', pipetteId: pipetteId ?? '', - mount: mount, + mount, }, }, { commandType: 'home' as const, params: {} }, { commandType: 'calibration/moveToMaintenancePosition' as const, params: { - mount: mount, + mount, }, }, ] @@ -191,7 +191,7 @@ export const BeforeBeginning = ( proceed() }) .catch(error => { - setShowErrorMessage(error.message) + setShowErrorMessage(error.message as string) }) } @@ -200,7 +200,7 @@ export const BeforeBeginning = ( { commandType: 'calibration/moveToMaintenancePosition' as const, params: { - mount: mount, + mount, }, }, ] @@ -227,7 +227,7 @@ export const BeforeBeginning = ( proceed() }) .catch(error => { - setShowErrorMessage(error.message) + setShowErrorMessage(error.message as string) }) } @@ -256,7 +256,7 @@ export const BeforeBeginning = ( /> {selectedPipette === NINETY_SIX_CHANNEL && flowType === FLOWS.ATTACH && - !isOnDevice && ( + !Boolean(isOnDevice) && ( {t('pipette_heavy', { weight: WEIGHT_OF_96_CHANNEL })} @@ -265,19 +265,23 @@ export const BeforeBeginning = ( {selectedPipette === NINETY_SIX_CHANNEL && (flowType === FLOWS.CALIBRATE || flowType === FLOWS.ATTACH ? ( - {isWasteChuteOnDeck + {Boolean(isWasteChuteOnDeck) ? t('waste_chute_error') : t('waste_chute_warning')} ) : ( {t('pipette_heavy', { weight: WEIGHT_OF_96_CHANNEL })} diff --git a/app/src/organisms/PipetteWizardFlows/Carriage.tsx b/app/src/organisms/PipetteWizardFlows/Carriage.tsx index a4c26f0fa6e..b32a04a8adf 100644 --- a/app/src/organisms/PipetteWizardFlows/Carriage.tsx +++ b/app/src/organisms/PipetteWizardFlows/Carriage.tsx @@ -43,7 +43,7 @@ export const Carriage = (props: PipetteWizardStepProps): JSX.Element | null => { proceed() }) .catch(error => { - setShowErrorMessage(error.message) + setShowErrorMessage(error.message as string) }) } @@ -62,7 +62,7 @@ export const Carriage = (props: PipetteWizardStepProps): JSX.Element | null => { )} rightHandBody={getPipetteAnimations96({ section: SECTIONS.CARRIAGE, - flowType: flowType, + flowType, })} bodyText={ { } back={flowType === FLOWS.ATTACH ? undefined : goBack} proceedButton={ - isOnDevice ? ( + Boolean(isOnDevice) ? ( ) : ( { : handleReattachCarriageProceed } > - {capitalize(t('shared:continue'))} + {capitalize(t('shared:continue') as string)} ) } diff --git a/app/src/organisms/PipetteWizardFlows/ChoosePipette.tsx b/app/src/organisms/PipetteWizardFlows/ChoosePipette.tsx index fb4c04ca5c4..0bd95be038d 100644 --- a/app/src/organisms/PipetteWizardFlows/ChoosePipette.tsx +++ b/app/src/organisms/PipetteWizardFlows/ChoosePipette.tsx @@ -136,7 +136,7 @@ export const ChoosePipette = (props: ChoosePipetteProps): JSX.Element => { }) const wizardHeader = ( { value: NINETY_SIX_CHANNEL, }} onSelect={event => { - setSelectedPipette(event.target.value as any) + setSelectedPipette(event.target.value as SelectablePipettes) }} initialSelected={selectedPipette} /> diff --git a/app/src/organisms/PipetteWizardFlows/DetachPipette.tsx b/app/src/organisms/PipetteWizardFlows/DetachPipette.tsx index 10871208a8c..fcd9df95266 100644 --- a/app/src/organisms/PipetteWizardFlows/DetachPipette.tsx +++ b/app/src/organisms/PipetteWizardFlows/DetachPipette.tsx @@ -115,7 +115,7 @@ export const DetachPipette = (props: DetachPipetteProps): JSX.Element => { proceed() }) .catch(error => { - setShowErrorMessage(error.message) + setShowErrorMessage(error.message as string) }) } @@ -163,7 +163,7 @@ export const DetachPipette = (props: DetachPipetteProps): JSX.Element => { {is96ChannelPipette && ( {t('pipette_heavy', { weight: WEIGHT_OF_96_CHANNEL })} @@ -178,13 +178,13 @@ export const DetachPipette = (props: DetachPipetteProps): JSX.Element => { return ( { {t('shared:go_back')} - {isOnDevice ? ( + {Boolean(isOnDevice) ? ( { ) : is96ChannelPipette ? ( getPipetteAnimations96({ section: pipetteWizardStep.section, - flowType: flowType, + flowType, }) ) : ( getPipetteAnimations({ pipetteWizardStep, channel }) diff --git a/app/src/organisms/PipetteWizardFlows/ExitModal.tsx b/app/src/organisms/PipetteWizardFlows/ExitModal.tsx index e385471b2c1..463e1907f40 100644 --- a/app/src/organisms/PipetteWizardFlows/ExitModal.tsx +++ b/app/src/organisms/PipetteWizardFlows/ExitModal.tsx @@ -38,7 +38,8 @@ export function ExitModal(props: ExitModalProps): JSX.Element { break } } - if (isRobotMoving) return + if (Boolean(isRobotMoving)) + return return ( diff --git a/app/src/organisms/PipetteWizardFlows/MountingPlate.tsx b/app/src/organisms/PipetteWizardFlows/MountingPlate.tsx index b2a1f3f197d..376f7e3afe2 100644 --- a/app/src/organisms/PipetteWizardFlows/MountingPlate.tsx +++ b/app/src/organisms/PipetteWizardFlows/MountingPlate.tsx @@ -43,12 +43,12 @@ export const MountingPlate = ( proceed() }) .catch(error => { - setShowErrorMessage(error.message) + setShowErrorMessage(error.message as string) }) } if (isRobotMoving) return - return errorMessage ? ( + return errorMessage != null ? ( { switch (flowType) { case FLOWS.CALIBRATE: { header = t(hasCalData ? 'pip_recal_success' : 'pip_cal_success', { - pipetteName: pipetteName, + pipetteName, }) break } @@ -95,7 +95,7 @@ export const Results = (props: ResultsProps): JSX.Element => { (attachedPipettes[mount] != null && requiredPipette == null) || Boolean(isCorrectPipette) ) { - header = t('pipette_attached', { pipetteName: pipetteName }) + header = t('pipette_attached', { pipetteName }) buttonText = t('cal_pipette') // attached wrong pipette } else if ( @@ -116,7 +116,7 @@ export const Results = (props: ResultsProps): JSX.Element => { } case FLOWS.DETACH: { if (attachedPipettes[mount] != null) { - header = t('pipette_failed_to_detach', { pipetteName: pipetteName }) + header = t('pipette_failed_to_detach', { pipetteName }) iconColor = COLORS.red50 isSuccess = false } else { @@ -173,7 +173,7 @@ export const Results = (props: ResultsProps): JSX.Element => { proceed() }) .catch(error => { - setShowErrorMessage(error.message) + setShowErrorMessage(error.message as string) }) } else if ( isSuccess && @@ -190,13 +190,13 @@ export const Results = (props: ResultsProps): JSX.Element => { params: { pipetteName: attachedPipettes[mount]?.instrumentName ?? '', pipetteId: attachedPipettes[mount]?.serialNumber ?? '', - mount: mount, + mount, }, }, { commandType: 'home' as const, params: { - axes: axes, + axes, }, }, ], @@ -206,13 +206,13 @@ export const Results = (props: ResultsProps): JSX.Element => { proceed() }) .catch(error => { - setShowErrorMessage(error.message) + setShowErrorMessage(error.message as string) }) } else { proceed() } } - let button: JSX.Element = isOnDevice ? ( + let button: JSX.Element = Boolean(isOnDevice) ? ( { numberOfTryAgains > 2 ? t('branded:something_seems_wrong') : undefined button = ( <> - {isOnDevice ? ( + {Boolean(isOnDevice) ? ( {t('shared:go_back')} @@ -324,7 +324,7 @@ export const Results = (props: ResultsProps): JSX.Element => { isPending={isFetching} width="100%" justifyContentForOddButton={ - isOnDevice && isSuccess ? ALIGN_FLEX_END : undefined + Boolean(isOnDevice) && isSuccess ? ALIGN_FLEX_END : undefined } > {button} diff --git a/app/src/organisms/PipetteWizardFlows/index.tsx b/app/src/organisms/PipetteWizardFlows/index.tsx index 3d7b8c21854..e3d6758ffcb 100644 --- a/app/src/organisms/PipetteWizardFlows/index.tsx +++ b/app/src/organisms/PipetteWizardFlows/index.tsx @@ -88,7 +88,8 @@ export const PipetteWizardFlows = ( ) const host = useHost() const [currentStepIndex, setCurrentStepIndex] = React.useState(0) - const totalStepCount = pipetteWizardSteps ? pipetteWizardSteps.length - 1 : 0 + const totalStepCount = + pipetteWizardSteps != null ? pipetteWizardSteps.length - 1 : 0 const currentStep = pipetteWizardSteps?.[currentStepIndex] ?? null const [isFetchingPipettes, setIsFetchingPipettes] = React.useState( false @@ -213,7 +214,7 @@ export const PipetteWizardFlows = ( }) .catch(error => { setIsExiting(true) - setShowErrorMessage(error.message) + setShowErrorMessage(error.message as string) }) } } diff --git a/app/src/organisms/ProtocolSetupModulesAndDeck/ModuleTable.tsx b/app/src/organisms/ProtocolSetupModulesAndDeck/ModuleTable.tsx index bc5142c1041..c9aab7b61ac 100644 --- a/app/src/organisms/ProtocolSetupModulesAndDeck/ModuleTable.tsx +++ b/app/src/organisms/ProtocolSetupModulesAndDeck/ModuleTable.tsx @@ -139,7 +139,7 @@ function ModuleTableItem({ const handleCalibrate = (): void => { if (module.attachedModuleMatch != null) { if (getModuleTooHot(module.attachedModuleMatch)) { - makeSnackbar(t('module_wizard_flows:module_too_hot')) + makeSnackbar(t('module_wizard_flows:module_too_hot') as string) } else { chainLiveCommands( getModulePrepCommands(module.attachedModuleMatch), @@ -150,7 +150,7 @@ function ModuleTableItem({ setShowModuleWizard(true) } } else { - makeSnackbar(t('attach_module')) + makeSnackbar(t('attach_module') as string) } } diff --git a/app/src/organisms/ProtocolSetupParameters/ChooseEnum.tsx b/app/src/organisms/ProtocolSetupParameters/ChooseEnum.tsx index aae386561b2..2845adca86e 100644 --- a/app/src/organisms/ProtocolSetupParameters/ChooseEnum.tsx +++ b/app/src/organisms/ProtocolSetupParameters/ChooseEnum.tsx @@ -44,7 +44,7 @@ export function ChooseEnum({ buttonText={t('restore_default')} onClickButton={() => { resetValueDisabled - ? makeSnackbar(t('no_custom_values')) + ? makeSnackbar(t('no_custom_values') as string) : setParameter(parameter.default, parameter.variableName) }} /> diff --git a/app/src/organisms/ProtocolSetupParameters/ChooseNumber.tsx b/app/src/organisms/ProtocolSetupParameters/ChooseNumber.tsx index 02cba23365d..1f5fcc1db19 100644 --- a/app/src/organisms/ProtocolSetupParameters/ChooseNumber.tsx +++ b/app/src/organisms/ProtocolSetupParameters/ChooseNumber.tsx @@ -45,12 +45,12 @@ export function ChooseNumber({ }, []) if (parameter.type !== 'int' && parameter.type !== 'float') { - console.log(`Incorrect parameter type: ${parameter.type}`) + console.log(`Incorrect parameter type: ${parameter.type as string}`) return null } const handleClickGoBack = (newValue: number | null): void => { if (error != null || newValue === null) { - makeSnackbar(t('value_out_of_range_generic')) + makeSnackbar(t('value_out_of_range_generic') as string) } else { setParameter(newValue, parameter.variableName) handleGoBack() @@ -96,7 +96,7 @@ export function ChooseNumber({ buttonText={t('restore_default')} onClickButton={() => { resetValueDisabled - ? makeSnackbar(t('no_custom_values')) + ? makeSnackbar(t('no_custom_values') as string) : setParamValue(String(parameter.default)) }} /> diff --git a/app/src/organisms/ProtocolSetupParameters/ViewOnlyParameters.tsx b/app/src/organisms/ProtocolSetupParameters/ViewOnlyParameters.tsx index c0572b1eae0..e655ff35d82 100644 --- a/app/src/organisms/ProtocolSetupParameters/ViewOnlyParameters.tsx +++ b/app/src/organisms/ProtocolSetupParameters/ViewOnlyParameters.tsx @@ -35,7 +35,7 @@ export function ViewOnlyParameters({ const { makeSnackbar } = useToaster() const mostRecentAnalysis = useMostRecentCompletedAnalysis(runId) const handleOnClick = (): void => { - makeSnackbar(t('reset_setup')) + makeSnackbar(t('reset_setup') as string) } const parameters = mostRecentAnalysis?.runTimeParameters ?? [] diff --git a/app/src/organisms/QuickTransferFlow/SelectDestWells.tsx b/app/src/organisms/QuickTransferFlow/SelectDestWells.tsx index ceedc589e1f..9536601c540 100644 --- a/app/src/organisms/QuickTransferFlow/SelectDestWells.tsx +++ b/app/src/organisms/QuickTransferFlow/SelectDestWells.tsx @@ -83,7 +83,7 @@ export function SelectDestWells(props: SelectDestWellsProps): JSX.Element { t('number_wells_selected_error_message', { wellCount: sourceWellCount, selectionUnits, - }), + }) as string, 'error', { closeButton: true, diff --git a/app/src/organisms/RobotSettingsDashboard/NetworkSettings/RobotSettingsJoinOtherNetwork.tsx b/app/src/organisms/RobotSettingsDashboard/NetworkSettings/RobotSettingsJoinOtherNetwork.tsx index 69f6118c263..b30d49098b6 100644 --- a/app/src/organisms/RobotSettingsDashboard/NetworkSettings/RobotSettingsJoinOtherNetwork.tsx +++ b/app/src/organisms/RobotSettingsDashboard/NetworkSettings/RobotSettingsJoinOtherNetwork.tsx @@ -30,7 +30,7 @@ export function RobotSettingsJoinOtherNetwork({ setSelectedSsid(inputSsid) setCurrentOption('RobotSettingsSelectAuthenticationType') } else { - setErrorMessage(t('join_other_network_error_message')) + setErrorMessage(t('join_other_network_error_message') as string) } } diff --git a/app/src/pages/ConnectViaWifi/JoinOtherNetwork.tsx b/app/src/pages/ConnectViaWifi/JoinOtherNetwork.tsx index bb2595f28f3..72a7315678c 100644 --- a/app/src/pages/ConnectViaWifi/JoinOtherNetwork.tsx +++ b/app/src/pages/ConnectViaWifi/JoinOtherNetwork.tsx @@ -27,7 +27,7 @@ export function JoinOtherNetwork({ setSelectedSsid(inputSsid) setCurrentOption('SelectAuthType') } else { - setErrorMessage(t('join_other_network_error_message')) + setErrorMessage(t('join_other_network_error_message') as string) } } diff --git a/app/src/pages/Labware/index.tsx b/app/src/pages/Labware/index.tsx index 943ef3ab249..ae35a39fbed 100644 --- a/app/src/pages/Labware/index.tsx +++ b/app/src/pages/Labware/index.tsx @@ -108,10 +108,14 @@ export function Labware(): JSX.Element { }) } else if (newLabwareName != null) { setShowAddLabwareSlideout(false) - makeToast(t('imported', { filename: newLabwareName }), SUCCESS_TOAST, { - closeButton: true, - onClose: clearLabwareName, - }) + makeToast( + t('imported', { filename: newLabwareName }) as string, + SUCCESS_TOAST, + { + closeButton: true, + onClose: clearLabwareName, + } + ) } // eslint-disable-next-line react-hooks/exhaustive-deps }, [labwareFailureMessage, newLabwareName]) diff --git a/app/src/pages/ProtocolDashboard/DeleteProtocolConfirmationModal.tsx b/app/src/pages/ProtocolDashboard/DeleteProtocolConfirmationModal.tsx index bb21e5e7815..7971b9f8237 100644 --- a/app/src/pages/ProtocolDashboard/DeleteProtocolConfirmationModal.tsx +++ b/app/src/pages/ProtocolDashboard/DeleteProtocolConfirmationModal.tsx @@ -74,7 +74,7 @@ export function DeleteProtocolConfirmationModal({ .then(() => { setShowIcon(false) setShowDeleteConfirmationModal(false) - makeSnackbar(t('protocol_deleted')) + makeSnackbar(t('protocol_deleted') as string) }) .catch((e: Error) => { console.error(`error deleting resources: ${e.message}`) diff --git a/app/src/pages/ProtocolDashboard/LongPressModal.tsx b/app/src/pages/ProtocolDashboard/LongPressModal.tsx index ecec24785a3..91fac6929fa 100644 --- a/app/src/pages/ProtocolDashboard/LongPressModal.tsx +++ b/app/src/pages/ProtocolDashboard/LongPressModal.tsx @@ -72,12 +72,12 @@ export function LongPressModal({ } else { pinnedProtocolIds.push(protocolId) handlePinnedProtocolIds(pinnedProtocolIds) - makeSnackbar(t('pinned_protocol')) + makeSnackbar(t('pinned_protocol') as string) } } else { pinnedProtocolIds = pinnedProtocolIds.filter(p => p !== protocolId) handlePinnedProtocolIds(pinnedProtocolIds) - makeSnackbar(t('unpinned_protocol')) + makeSnackbar(t('unpinned_protocol') as string) } } diff --git a/app/src/pages/ProtocolDetails/Hardware.tsx b/app/src/pages/ProtocolDetails/Hardware.tsx index a481fd9dfa8..113647dbda8 100644 --- a/app/src/pages/ProtocolDetails/Hardware.tsx +++ b/app/src/pages/ProtocolDetails/Hardware.tsx @@ -111,7 +111,7 @@ function HardwareItem({ let location: JSX.Element = ( - {i18n.format(getHardwareLocation(hardware, t), 'titleCase')} + {i18n.format(getHardwareLocation(hardware, t as TFunction), 'titleCase')} ) if (hardware.hardwareType === 'module') { diff --git a/app/src/pages/ProtocolDetails/Parameters.tsx b/app/src/pages/ProtocolDetails/Parameters.tsx index ab81d463a2e..7d28277d26c 100644 --- a/app/src/pages/ProtocolDetails/Parameters.tsx +++ b/app/src/pages/ProtocolDetails/Parameters.tsx @@ -60,7 +60,7 @@ export const Parameters = (props: { protocolId: string }): JSX.Element => { const { t, i18n } = useTranslation('protocol_details') const makeSnack = (): void => { - makeSnackbar(t('start_setup_customize_values')) + makeSnackbar(t('start_setup_customize_values') as string) } const formatRange = (parameter: RunTimeParameter): string => { diff --git a/app/src/pages/ProtocolDetails/index.tsx b/app/src/pages/ProtocolDetails/index.tsx index d3d97fc8e9c..a6f8e45e56e 100644 --- a/app/src/pages/ProtocolDetails/index.tsx +++ b/app/src/pages/ProtocolDetails/index.tsx @@ -387,11 +387,11 @@ export function ProtocolDetails(): JSX.Element | null { setShowMaxPinsAlert(true) } else { pinnedProtocolIds.push(protocolId) - makeSnackbar(t('protocol_info:pinned_protocol')) + makeSnackbar(t('protocol_info:pinned_protocol') as string) } } else { pinnedProtocolIds = pinnedProtocolIds.filter(p => p !== protocolId) - makeSnackbar(t('protocol_info:unpinned_protocol')) + makeSnackbar(t('protocol_info:unpinned_protocol') as string) } dispatch( updateConfigValue('protocols.pinnedProtocolIds', pinnedProtocolIds) diff --git a/app/src/pages/ProtocolSetup/index.tsx b/app/src/pages/ProtocolSetup/index.tsx index 914d2990100..dd077e0585b 100644 --- a/app/src/pages/ProtocolSetup/index.tsx +++ b/app/src/pages/ProtocolSetup/index.tsx @@ -502,7 +502,7 @@ function PrepareToRun({ incompleteInstrumentCount === 0 && areModulesReady && areFixturesReady const onPlay = (): void => { if (isDoorOpen) { - makeSnackbar(t('shared:close_robot_door')) + makeSnackbar(t('shared:close_robot_door') as string) } else { if ( isHeaterShakerInProtocol && @@ -515,7 +515,7 @@ function PrepareToRun({ play() trackProtocolRunEvent({ name: ANALYTICS_PROTOCOL_RUN_ACTION.START, - properties: robotAnalyticsData != null ? robotAnalyticsData : {}, + properties: robotAnalyticsData ?? {}, }) } else { makeSnackbar( diff --git a/app/src/redux/analytics/epic.ts b/app/src/redux/analytics/epic.ts index 3a199dbee67..3380fd590c6 100644 --- a/app/src/redux/analytics/epic.ts +++ b/app/src/redux/analytics/epic.ts @@ -15,7 +15,7 @@ import { getAnalyticsConfig, getAnalyticsOptedIn } from './selectors' import { initializeMixpanel, setMixpanelTracking, trackEvent } from './mixpanel' import { makeEvent } from './make-event' -import type { Observable } from 'rxjs' +import type { Observable, OperatorFunction } from 'rxjs' import type { State, Action, Epic } from '../types' import type { ConfigInitializedAction } from '../config/types' import type { TrackEventArgs, AnalyticsEvent, AnalyticsConfig } from './types' @@ -27,7 +27,7 @@ const initializeAnalyticsEpic: Epic = (action$, state$) => { const { config } = initAction.payload initializeMixpanel(config.analytics, config.isOnDevice) }), - ignoreElements() + ignoreElements() as OperatorFunction ) } @@ -45,12 +45,15 @@ const sendAnalyticsEventEpic: Epic = (action$, state$) => { AnalyticsConfig ] => { const [maybeEvent, maybeConfig] = args - return Boolean(maybeEvent && maybeConfig) + return Boolean(maybeEvent != null && maybeConfig) }), tap(([event, config]: [AnalyticsEvent, AnalyticsConfig]) => { trackEvent(event, config) }), - ignoreElements() + ignoreElements() as OperatorFunction< + [AnalyticsEvent, { appId: string; optedIn: boolean; seenOptIn: boolean }], + never + > ) } @@ -67,7 +70,7 @@ const optIntoAnalyticsEpic: Epic = (_, state$) => { if (state.config?.analytics != null) setMixpanelTracking(state.config?.analytics, state.config?.isOnDevice) }), - ignoreElements() + ignoreElements() as OperatorFunction<[State, State], never> ) } diff --git a/app/src/redux/analytics/mixpanel.ts b/app/src/redux/analytics/mixpanel.ts index 924d4b5b312..20a5a2ed170 100644 --- a/app/src/redux/analytics/mixpanel.ts +++ b/app/src/redux/analytics/mixpanel.ts @@ -26,7 +26,7 @@ export function initializeMixpanel( config: AnalyticsConfig, isOnDevice: boolean | null ): void { - if (MIXPANEL_ID) { + if (MIXPANEL_ID != null) { initMixpanelInstanceOnce(config) setMixpanelTracking(config, isOnDevice) trackEvent({ name: 'appOpen', properties: {} }, config) @@ -42,10 +42,10 @@ export function trackEvent( const { optedIn } = config log.debug('Trackable event', { event, optedIn }) - if (MIXPANEL_ID && optedIn) { - if (event.superProperties) mixpanel.register(event.superProperties) - // @ts-expect-error TODO protect for no name on event and add test case - if (event.name) mixpanel.track(event.name, event.properties) + if (MIXPANEL_ID != null && optedIn) { + if (event.superProperties != null) mixpanel.register(event.superProperties) + if ('name' in event && event.name != null) + mixpanel.track(event.name, event.properties) } } @@ -53,7 +53,7 @@ export function setMixpanelTracking( config: AnalyticsConfig, isOnDevice: boolean | null ): void { - if (MIXPANEL_ID) { + if (MIXPANEL_ID != null) { initMixpanelInstanceOnce(config) if (config.optedIn) { log.debug('User has opted into analytics; tracking with Mixpanel') @@ -62,7 +62,7 @@ export function setMixpanelTracking( mixpanel.register({ appVersion: CURRENT_VERSION, appId: config.appId, - appMode: isOnDevice ? 'ODD' : 'Desktop', + appMode: Boolean(isOnDevice) ? 'ODD' : 'Desktop', }) } else { log.debug('User has opted out of analytics; stopping tracking') @@ -78,7 +78,7 @@ function initializeMixpanelInstanceOnce( let hasBeenInitialized = false return function (config: AnalyticsConfig): undefined { - if (!hasBeenInitialized && MIXPANEL_ID) { + if (!hasBeenInitialized && MIXPANEL_ID != null) { hasBeenInitialized = true log.debug('Initializing Mixpanel', { config }) mixpanel.init(MIXPANEL_ID, MIXPANEL_OPTS) diff --git a/app/src/redux/calibration/epic/fetchCalibrationStatusEpic.ts b/app/src/redux/calibration/epic/fetchCalibrationStatusEpic.ts index 5eacede77fa..08d2b3a2572 100644 --- a/app/src/redux/calibration/epic/fetchCalibrationStatusEpic.ts +++ b/app/src/redux/calibration/epic/fetchCalibrationStatusEpic.ts @@ -10,7 +10,8 @@ import type { ResponseToActionMapper, } from '../../robot-api/operators' import type { Action, Epic } from '../../types' -import type { FetchCalibrationStatusAction } from '../types' +import type { CalibrationStatus, FetchCalibrationStatusAction } from '../types' +import type { RobotApiErrorResponse } from '../../robot-api/types' const mapActionToRequest: ActionToRequestMapper = action => ({ method: GET, @@ -25,8 +26,16 @@ const mapResponseToAction: ResponseToActionMapper const meta = { ...originalAction.meta, response: responseMeta } return response.ok - ? Actions.fetchCalibrationStatusSuccess(host.name, body, meta) - : Actions.fetchCalibrationStatusFailure(host.name, body, meta) + ? Actions.fetchCalibrationStatusSuccess( + host.name, + body as CalibrationStatus, + meta + ) + : Actions.fetchCalibrationStatusFailure( + host.name, + body as RobotApiErrorResponse, + meta + ) } export const fetchCalibrationStatusEpic: Epic = (action$, state$) => { diff --git a/app/src/redux/calibration/pipette-offset/epic/fetchPipetteOffsetCalibrationsEpic.ts b/app/src/redux/calibration/pipette-offset/epic/fetchPipetteOffsetCalibrationsEpic.ts index 03f3f03a2c8..ddbeeba31fc 100644 --- a/app/src/redux/calibration/pipette-offset/epic/fetchPipetteOffsetCalibrationsEpic.ts +++ b/app/src/redux/calibration/pipette-offset/epic/fetchPipetteOffsetCalibrationsEpic.ts @@ -11,6 +11,8 @@ import type { } from '../../../robot-api/operators' import type { Action, Epic } from '../../../types' import type { FetchPipetteOffsetCalibrationsAction } from '../types' +import type { AllPipetteOffsetCalibrations } from '../../api-types' +import type { RobotApiErrorResponse } from '../../../robot-api/types' const mapActionToRequest: ActionToRequestMapper = action => ({ method: GET, @@ -24,8 +26,16 @@ const mapResponseToAction: ResponseToActionMapper { diff --git a/app/src/redux/calibration/tip-length/epic/fetchTipLengthCalibrationsEpic.ts b/app/src/redux/calibration/tip-length/epic/fetchTipLengthCalibrationsEpic.ts index 89ba34cb852..1b99bbfef3c 100644 --- a/app/src/redux/calibration/tip-length/epic/fetchTipLengthCalibrationsEpic.ts +++ b/app/src/redux/calibration/tip-length/epic/fetchTipLengthCalibrationsEpic.ts @@ -11,6 +11,8 @@ import type { } from '../../../robot-api/operators' import type { Action, Epic } from '../../../types' import type { FetchTipLengthCalibrationsAction } from '../types' +import type { AllTipLengthCalibrations } from '../../api-types' +import type { RobotApiErrorResponse } from '../../../robot-api/types' const mapActionToRequest: ActionToRequestMapper = action => ({ method: GET, @@ -24,8 +26,16 @@ const mapResponseToAction: ResponseToActionMapper { diff --git a/app/src/redux/discovery/epic.ts b/app/src/redux/discovery/epic.ts index c38d124b728..4940d5eccc6 100644 --- a/app/src/redux/discovery/epic.ts +++ b/app/src/redux/discovery/epic.ts @@ -23,11 +23,10 @@ export const startDiscoveryEpic: Epic = action$ => StartDiscoveryAction | UiInitializedAction, Observable >(startAction => { - // @ts-expect-error TODO: use in operator to protect against accessing timeout when it doesn't exist - const timeout = startAction.payload - ? // @ts-expect-error TODO: use in operator to protect against accessing timeout when it doesn't exist - startAction.payload.timeout ?? DISCOVERY_TIMEOUT_MS - : DISCOVERY_TIMEOUT_MS + const timeout = + 'payload' in startAction && startAction.payload != null + ? startAction.payload.timeout ?? DISCOVERY_TIMEOUT_MS + : DISCOVERY_TIMEOUT_MS return of(finishDiscovery()).pipe(delay(timeout)) }) diff --git a/app/src/redux/modules/epic/updateModuleEpic.ts b/app/src/redux/modules/epic/updateModuleEpic.ts index 8289e7c28c3..925ed7cc28e 100644 --- a/app/src/redux/modules/epic/updateModuleEpic.ts +++ b/app/src/redux/modules/epic/updateModuleEpic.ts @@ -14,6 +14,7 @@ import type { } from '../../robot-api/operators' import type { UpdateModuleAction } from '../types' +import type { RobotApiErrorResponse } from '../../robot-api/types' const mapActionToRequest: ActionToRequestMapper = action => ({ method: POST, @@ -29,8 +30,18 @@ const mapResponseToAction: ResponseToActionMapper = ( const meta = { ...originalAction.meta, response: responseMeta } return response.ok - ? Actions.updateModuleSuccess(host.name, moduleId, body.message, meta) - : Actions.updateModuleFailure(host.name, moduleId, body, meta) + ? Actions.updateModuleSuccess( + host.name, + moduleId, + body.message as string, + meta + ) + : Actions.updateModuleFailure( + host.name, + moduleId, + body as RobotApiErrorResponse, + meta + ) } export const updateModuleEpic: Epic = (action$, state$) => { diff --git a/app/src/redux/networking/epic/disconnectEpic.ts b/app/src/redux/networking/epic/disconnectEpic.ts index 56f93672ba1..62761462204 100644 --- a/app/src/redux/networking/epic/disconnectEpic.ts +++ b/app/src/redux/networking/epic/disconnectEpic.ts @@ -11,6 +11,7 @@ import type { } from '../../robot-api/operators' import type { Action, Epic } from '../../types' import type { PostWifiDisconnectAction } from '../types' +import type { RobotApiErrorResponse } from '../../robot-api/types' const mapActionToRequest: ActionToRequestMapper = action => ({ method: POST, @@ -27,7 +28,11 @@ const mapResponseToAction: ResponseToActionMapper = ( return response.ok ? Actions.postWifiDisconnectSuccess(host.name, meta) - : Actions.postWifiDisconnectFailure(host.name, body, meta) + : Actions.postWifiDisconnectFailure( + host.name, + body as RobotApiErrorResponse, + meta + ) } const postDisconnectEpic: Epic = (action$, state$) => diff --git a/app/src/redux/networking/epic/fetchEapOptionsEpic.ts b/app/src/redux/networking/epic/fetchEapOptionsEpic.ts index b3f4438324c..7a704552ec5 100644 --- a/app/src/redux/networking/epic/fetchEapOptionsEpic.ts +++ b/app/src/redux/networking/epic/fetchEapOptionsEpic.ts @@ -10,7 +10,8 @@ import type { ResponseToActionMapper, } from '../../robot-api/operators' import type { Action, Epic } from '../../types' -import type { FetchEapOptionsAction } from '../types' +import type { EapOption, FetchEapOptionsAction } from '../types' +import type { RobotApiErrorResponse } from '../../robot-api/types' const mapActionToRequest: ActionToRequestMapper = action => ({ method: GET, @@ -25,8 +26,8 @@ const mapResponseToAction: ResponseToActionMapper = ( const meta = { ...originalAction.meta, response: responseMeta } return response.ok - ? fetchEapOptionsSuccess(host.name, body.options, meta) - : fetchEapOptionsFailure(host.name, body, meta) + ? fetchEapOptionsSuccess(host.name, body.options as EapOption[], meta) + : fetchEapOptionsFailure(host.name, body as RobotApiErrorResponse, meta) } export const fetchEapOptionsEpic: Epic = (action$, state$) => { diff --git a/app/src/redux/networking/epic/fetchWifiKeysEpic.ts b/app/src/redux/networking/epic/fetchWifiKeysEpic.ts index d0cdd41e08c..d214bb6e54a 100644 --- a/app/src/redux/networking/epic/fetchWifiKeysEpic.ts +++ b/app/src/redux/networking/epic/fetchWifiKeysEpic.ts @@ -10,7 +10,8 @@ import type { ResponseToActionMapper, } from '../../robot-api/operators' import type { Action, Epic } from '../../types' -import type { FetchWifiKeysAction } from '../types' +import type { ApiWifiKey, FetchWifiKeysAction } from '../types' +import type { RobotApiErrorResponse } from '../../robot-api/types' const mapActionToRequest: ActionToRequestMapper = action => ({ method: GET, @@ -25,8 +26,8 @@ const mapResponseToAction: ResponseToActionMapper = ( const meta = { ...originalAction.meta, response: responseMeta } return response.ok - ? fetchWifiKeysSuccess(host.name, body.keys, meta) - : fetchWifiKeysFailure(host.name, body, meta) + ? fetchWifiKeysSuccess(host.name, body.keys as ApiWifiKey[], meta) + : fetchWifiKeysFailure(host.name, body as RobotApiErrorResponse, meta) } export const fetchWifiKeysEpic: Epic = (action$, state$) => { diff --git a/app/src/redux/networking/epic/postWifiKeysEpic.ts b/app/src/redux/networking/epic/postWifiKeysEpic.ts index 383a9c6bbf5..20050af8075 100644 --- a/app/src/redux/networking/epic/postWifiKeysEpic.ts +++ b/app/src/redux/networking/epic/postWifiKeysEpic.ts @@ -12,6 +12,7 @@ import type { } from '../../robot-api/operators' import type { Action, Epic } from '../../types' import type { PostWifiKeysAction, WifiKey } from '../types' +import type { RobotApiErrorResponse } from '../../robot-api/types' const mapActionToRequest: ActionToRequestMapper = action => { const { keyFile } = action.payload @@ -30,7 +31,7 @@ const mapResponseToAction: ResponseToActionMapper = ( return response.ok ? postWifiKeysSuccess(host.name, omit(body, 'message') as WifiKey, meta) - : postWifiKeysFailure(host.name, body, meta) + : postWifiKeysFailure(host.name, body as RobotApiErrorResponse, meta) } export const postWifiKeysEpic: Epic = (action$, state$) => { diff --git a/app/src/redux/networking/epic/statusEpic.ts b/app/src/redux/networking/epic/statusEpic.ts index 5779cfa6d97..861d954bae8 100644 --- a/app/src/redux/networking/epic/statusEpic.ts +++ b/app/src/redux/networking/epic/statusEpic.ts @@ -10,7 +10,12 @@ import type { ResponseToActionMapper, } from '../../robot-api/operators' import type { Action, Epic } from '../../types' -import type { FetchStatusAction } from '../types' +import type { + FetchStatusAction, + InterfaceStatus, + InternetStatus, +} from '../types' +import type { RobotApiErrorResponse } from '../../robot-api/types' const mapActionToRequest: ActionToRequestMapper = action => ({ method: GET, @@ -25,8 +30,13 @@ const mapResponseToAction: ResponseToActionMapper = ( const meta = { ...originalAction.meta, response: responseMeta } return response.ok - ? Actions.fetchStatusSuccess(host.name, body.status, body.interfaces, meta) - : Actions.fetchStatusFailure(host.name, body, meta) + ? Actions.fetchStatusSuccess( + host.name, + body.status as InternetStatus, + body.interfaces as Record, + meta + ) + : Actions.fetchStatusFailure(host.name, body as RobotApiErrorResponse, meta) } export const statusEpic: Epic = (action$, state$) => { diff --git a/app/src/redux/networking/epic/wifiConfigureEpic.ts b/app/src/redux/networking/epic/wifiConfigureEpic.ts index 5e7cb7b9388..95d46f95c6e 100644 --- a/app/src/redux/networking/epic/wifiConfigureEpic.ts +++ b/app/src/redux/networking/epic/wifiConfigureEpic.ts @@ -17,6 +17,7 @@ import type { PostWifiConfigureAction, PostWifiConfigureSuccessAction, } from '../types' +import type { RobotApiErrorResponse } from '../../robot-api/types' const mapActionToRequest: ActionToRequestMapper = action => ({ method: POST, @@ -32,8 +33,12 @@ const mapResponseToAction: ResponseToActionMapper = ( const meta = { ...originalAction.meta, response: responseMeta } return response.ok - ? Actions.postWifiConfigureSuccess(host.name, body.ssid, meta) - : Actions.postWifiConfigureFailure(host.name, body, meta) + ? Actions.postWifiConfigureSuccess(host.name, body.ssid as string, meta) + : Actions.postWifiConfigureFailure( + host.name, + body as RobotApiErrorResponse, + meta + ) } const postWifiConfigureEpic: Epic = (action$, state$) => { diff --git a/app/src/redux/pipettes/epic/fetchPipetteSettingsEpic.ts b/app/src/redux/pipettes/epic/fetchPipetteSettingsEpic.ts index 092931ee79a..d71bc3a2ca9 100644 --- a/app/src/redux/pipettes/epic/fetchPipetteSettingsEpic.ts +++ b/app/src/redux/pipettes/epic/fetchPipetteSettingsEpic.ts @@ -13,7 +13,7 @@ import type { ResponseToActionMapper, } from '../../robot-api/operators' -import type { FetchPipetteSettingsAction } from '../types' +import type { FetchPipetteSettingsAction, PipetteSettings } from '../types' const mapActionToRequest: ActionToRequestMapper = action => ({ method: GET, @@ -28,8 +28,16 @@ const mapResponseToAction: ResponseToActionMapper = const meta = { ...originalAction.meta, response: responseMeta } return response.ok - ? Actions.fetchPipetteSettingsSuccess(host.name, body, meta) - : Actions.fetchPipetteSettingsFailure(host.name, body, meta) + ? Actions.fetchPipetteSettingsSuccess( + host.name, + body as Record, + meta + ) + : Actions.fetchPipetteSettingsFailure( + host.name, + body as Record, + meta + ) } export const fetchPipetteSettingsEpic: Epic = (action$, state$) => { diff --git a/app/src/redux/pipettes/epic/fetchPipettesEpic.ts b/app/src/redux/pipettes/epic/fetchPipettesEpic.ts index 09bf424bf35..81344330e4b 100644 --- a/app/src/redux/pipettes/epic/fetchPipettesEpic.ts +++ b/app/src/redux/pipettes/epic/fetchPipettesEpic.ts @@ -14,6 +14,7 @@ import type { } from '../../robot-api/operators' import type { FetchPipettesAction } from '../types' +import type { FetchPipettesResponseBody } from '@opentrons/api-client' const mapActionToRequest: ActionToRequestMapper = action => ({ method: GET, @@ -29,8 +30,16 @@ const mapResponseToAction: ResponseToActionMapper = ( const meta = { ...originalAction.meta, response: responseMeta } return response.ok - ? Actions.fetchPipettesSuccess(host.name, body, meta) - : Actions.fetchPipettesFailure(host.name, body, meta) + ? Actions.fetchPipettesSuccess( + host.name, + body as FetchPipettesResponseBody, + meta + ) + : Actions.fetchPipettesFailure( + host.name, + body as Record, + meta + ) } export const fetchPipettesEpic: Epic = (action$, state$) => { diff --git a/app/src/redux/pipettes/epic/updatePipetteSettingsEpic.ts b/app/src/redux/pipettes/epic/updatePipetteSettingsEpic.ts index 71b767fb955..78ffb4eb84b 100644 --- a/app/src/redux/pipettes/epic/updatePipetteSettingsEpic.ts +++ b/app/src/redux/pipettes/epic/updatePipetteSettingsEpic.ts @@ -14,7 +14,10 @@ import type { ResponseToActionMapper, } from '../../robot-api/operators' -import type { UpdatePipetteSettingsAction } from '../types' +import type { + PipetteSettingsFieldsMap, + UpdatePipetteSettingsAction, +} from '../types' const mapActionToRequest: ActionToRequestMapper = action => ({ method: PATCH, @@ -38,10 +41,15 @@ const mapResponseToAction: ResponseToActionMapper = ? Actions.updatePipetteSettingsSuccess( host.name, pipetteId, - body.fields, + body.fields as PipetteSettingsFieldsMap, + meta + ) + : Actions.updatePipetteSettingsFailure( + host.name, + pipetteId, + body as Record, meta ) - : Actions.updatePipetteSettingsFailure(host.name, pipetteId, body, meta) } export const updatePipetteSettingsEpic: Epic = (action$, state$) => { diff --git a/app/src/redux/reducer.ts b/app/src/redux/reducer.ts index d2e8ae05c74..5bf33bb3b38 100644 --- a/app/src/redux/reducer.ts +++ b/app/src/redux/reducer.ts @@ -1,6 +1,7 @@ import createHistory from 'history/createHashHistory' import { combineReducers } from 'redux' import { connectRouter } from 'connected-react-router' +import type { RouterState } from 'connected-react-router' // api state import { robotApiReducer } from './robot-api/reducer' @@ -52,6 +53,7 @@ import { protocolStorageReducer } from './protocol-storage/reducer' import type { Reducer } from 'redux' import type { State, Action } from './types' +import type { History } from 'history' export const history = createHistory() @@ -75,8 +77,7 @@ export const rootReducer: Reducer = combineReducers< sessions: sessionReducer, calibration: calibrationReducer, protocolStorage: protocolStorageReducer, - router: connectRouter(history) as Reducer< - State['router'], - Action - >, + router: connectRouter( + history as History> + ) as Reducer, }) diff --git a/app/src/redux/robot-admin/epic/fetchResetOptionsEpic.ts b/app/src/redux/robot-admin/epic/fetchResetOptionsEpic.ts index f7efa31777e..97e517ef3ff 100644 --- a/app/src/redux/robot-admin/epic/fetchResetOptionsEpic.ts +++ b/app/src/redux/robot-admin/epic/fetchResetOptionsEpic.ts @@ -27,7 +27,11 @@ const mapResponseToAction: ResponseToActionMapper return response.ok ? Actions.fetchResetConfigOptionsSuccess(host.name, options, meta) - : Actions.fetchResetConfigOptionsFailure(host.name, body, meta) + : Actions.fetchResetConfigOptionsFailure( + host.name, + body as Record, + meta + ) } export const fetchResetOptionsEpic: Epic = (action$, state$) => { diff --git a/app/src/redux/robot-admin/epic/resetConfigEpic.ts b/app/src/redux/robot-admin/epic/resetConfigEpic.ts index c4b69445938..7a87ca2dd48 100644 --- a/app/src/redux/robot-admin/epic/resetConfigEpic.ts +++ b/app/src/redux/robot-admin/epic/resetConfigEpic.ts @@ -32,7 +32,11 @@ const mapResponseToAction: ResponseToActionMapper = ( return response.ok ? Actions.resetConfigSuccess(host.name, meta) - : Actions.resetConfigFailure(host.name, body, meta) + : Actions.resetConfigFailure( + host.name, + body as Record, + meta + ) } export const resetConfigEpic: Epic = (action$, state$) => { diff --git a/app/src/redux/robot-admin/epic/restartEpic.ts b/app/src/redux/robot-admin/epic/restartEpic.ts index 3b5e4b8b96f..1b5c1fe0bb7 100644 --- a/app/src/redux/robot-admin/epic/restartEpic.ts +++ b/app/src/redux/robot-admin/epic/restartEpic.ts @@ -22,7 +22,7 @@ const mapActionToRequest: ActionToRequestMapper = ( state ) => { const path = - getRobotRestartPath(state, action.payload.robotName) || + getRobotRestartPath(state, action.payload.robotName) ?? Constants.RESTART_PATH return { method: POST, path } @@ -38,7 +38,11 @@ const mapResponseToAction: ResponseToActionMapper = ( return response.ok ? Actions.restartRobotSuccess(host.name, meta) - : Actions.restartRobotFailure(host.name, body, meta) + : Actions.restartRobotFailure( + host.name, + body as Record, + meta + ) } export const restartEpic: Epic = (action$, state$) => { diff --git a/app/src/redux/robot-admin/epic/syncSystemTimeEpic.ts b/app/src/redux/robot-admin/epic/syncSystemTimeEpic.ts index 93a01f32906..f670258b089 100644 --- a/app/src/redux/robot-admin/epic/syncSystemTimeEpic.ts +++ b/app/src/redux/robot-admin/epic/syncSystemTimeEpic.ts @@ -7,8 +7,12 @@ import { withRobotHost } from '../../robot-api/operators' import * as Constants from '../constants' import type { Action, Epic } from '../../types' -import type { RobotApiRequestOptions } from '../../robot-api/types' +import type { + RobotApiRequestOptions, + RobotApiResponse, +} from '../../robot-api/types' import type { SyncSystemTimeAction } from '../types' +import type { OperatorFunction } from 'rxjs' const SYNC_THRESHOLD_SEC = 60 @@ -43,7 +47,7 @@ export const syncSystemTimeEpic: Epic = (action$, state$) => { filter(response => response.ok), map(response => response.body.data.systemTime), filter(systemTimeString => { - const systemTime = parseISO(systemTimeString) + const systemTime = parseISO(systemTimeString as string) const drift = differenceInSeconds(systemTime, new Date()) return Math.abs(drift) > SYNC_THRESHOLD_SEC }), @@ -53,6 +57,6 @@ export const syncSystemTimeEpic: Epic = (action$, state$) => { }) ) }), - ignoreElements() + ignoreElements() as OperatorFunction ) } diff --git a/app/src/redux/robot-controls/epic/fetchLightsEpic.ts b/app/src/redux/robot-controls/epic/fetchLightsEpic.ts index a3bc0816fba..1c0d09d7e06 100644 --- a/app/src/redux/robot-controls/epic/fetchLightsEpic.ts +++ b/app/src/redux/robot-controls/epic/fetchLightsEpic.ts @@ -28,8 +28,8 @@ const mapResponseToAction: ResponseToActionMapper = ( const meta = { ...originalAction.meta, response: responseMeta } return response.ok - ? Actions.fetchLightsSuccess(host.name, body.on, meta) - : Actions.fetchLightsFailure(host.name, body, meta) + ? Actions.fetchLightsSuccess(host.name, body.on as boolean, meta) + : Actions.fetchLightsFailure(host.name, body as { message: string }, meta) } export const fetchLightsEpic: Epic = (action$, state$) => { diff --git a/app/src/redux/robot-controls/epic/homeEpic.ts b/app/src/redux/robot-controls/epic/homeEpic.ts index dedb783fd21..cb627cc16fa 100644 --- a/app/src/redux/robot-controls/epic/homeEpic.ts +++ b/app/src/redux/robot-controls/epic/homeEpic.ts @@ -33,7 +33,7 @@ const mapResponseToAction: ResponseToActionMapper = ( return response.ok ? Actions.homeSuccess(host.name, meta) - : Actions.homeFailure(host.name, body, meta) + : Actions.homeFailure(host.name, body as { message: string }, meta) } export const homeEpic: Epic = (action$, state$) => { diff --git a/app/src/redux/robot-controls/epic/moveEpic.ts b/app/src/redux/robot-controls/epic/moveEpic.ts index ee05b165a0b..94c7f71d38e 100644 --- a/app/src/redux/robot-controls/epic/moveEpic.ts +++ b/app/src/redux/robot-controls/epic/moveEpic.ts @@ -38,7 +38,7 @@ const mapActionToRequest = ( mount, target: Constants.PIPETTE, point: apiPosition.point, - model: attachedPipettes[mount]?.model || null, + model: attachedPipettes[mount]?.model ?? null, } return { method: POST, path: Constants.MOVE_PATH, body } @@ -53,7 +53,7 @@ const mapResponseToAction = ( return response.ok ? Actions.moveSuccess(host.name, meta) - : Actions.moveFailure(host.name, body, meta) + : Actions.moveFailure(host.name, body as { message: string }, meta) } const fetchPositionsRequest = { method: GET, path: Constants.POSITIONS_PATH } @@ -82,7 +82,11 @@ export const moveEpic: Epic = (action$, state$) => { return positionsResponse.ok ? fetchRobotApi( host, - mapActionToRequest(action, state, positionsResponse.body) + mapActionToRequest( + action, + state, + positionsResponse.body as PositionsResponse + ) ) : of(positionsResponse) }), diff --git a/app/src/redux/robot-controls/epic/updateLightsEpic.ts b/app/src/redux/robot-controls/epic/updateLightsEpic.ts index a3d643b15e4..48ff4652995 100644 --- a/app/src/redux/robot-controls/epic/updateLightsEpic.ts +++ b/app/src/redux/robot-controls/epic/updateLightsEpic.ts @@ -33,8 +33,8 @@ const mapResponseToAction: ResponseToActionMapper = ( } return response.ok - ? Actions.updateLightsSuccess(host.name, body.on, meta) - : Actions.updateLightsFailure(host.name, body, meta) + ? Actions.updateLightsSuccess(host.name, body.on as boolean, meta) + : Actions.updateLightsFailure(host.name, body as { message: string }, meta) } export const updateLightsEpic: Epic = (action$, state$) => { diff --git a/app/src/redux/robot-settings/epic/fetchSettingsEpic.ts b/app/src/redux/robot-settings/epic/fetchSettingsEpic.ts index 281648ebf94..34d0d237878 100644 --- a/app/src/redux/robot-settings/epic/fetchSettingsEpic.ts +++ b/app/src/redux/robot-settings/epic/fetchSettingsEpic.ts @@ -13,7 +13,7 @@ import type { ResponseToActionMapper, } from '../../robot-api/operators' -import type { FetchSettingsAction } from '../types' +import type { FetchSettingsAction, RobotSettings } from '../types' const mapActionToRequest: ActionToRequestMapper = () => ({ method: GET, @@ -30,11 +30,11 @@ const mapResponseToAction: ResponseToActionMapper = ( return response.ok ? Actions.fetchSettingsSuccess( host.name, - body.settings, - body.links?.restart || null, + body.settings as RobotSettings, + (body.links?.restart as string | null) ?? null, meta ) - : Actions.fetchSettingsFailure(host.name, body, meta) + : Actions.fetchSettingsFailure(host.name, body as { message: string }, meta) } export const fetchSettingsEpic: Epic = (action$, state$) => { diff --git a/app/src/redux/robot-settings/epic/updateSettingEpic.ts b/app/src/redux/robot-settings/epic/updateSettingEpic.ts index a6b8447156d..5cd32e4b02c 100644 --- a/app/src/redux/robot-settings/epic/updateSettingEpic.ts +++ b/app/src/redux/robot-settings/epic/updateSettingEpic.ts @@ -13,7 +13,7 @@ import type { ResponseToActionMapper, } from '../../robot-api/operators' -import type { UpdateSettingAction } from '../types' +import type { RobotSettings, UpdateSettingAction } from '../types' const mapActionToRequest: ActionToRequestMapper = action => ({ method: POST, @@ -31,11 +31,11 @@ const mapResponseToAction: ResponseToActionMapper = ( return response.ok ? Actions.updateSettingSuccess( host.name, - body.settings, - body.links?.restart || null, + body.settings as RobotSettings, + (body.links?.restart as string | null) ?? null, meta ) - : Actions.updateSettingFailure(host.name, body, meta) + : Actions.updateSettingFailure(host.name, body as { message: string }, meta) } export const updateSettingEpic: Epic = (action$, state$) => { diff --git a/app/src/redux/robot-update/epic.ts b/app/src/redux/robot-update/epic.ts index f3ec8fcfacf..0c063ea4931 100644 --- a/app/src/redux/robot-update/epic.ts +++ b/app/src/redux/robot-update/epic.ts @@ -79,6 +79,7 @@ import type { RobotUpdateSession, RobotUpdateStatusAction, RobotUpdateFileInfoAction, + UpdateSessionStage, } from './types' export const POLL_INTERVAL_MS = 2000 @@ -113,7 +114,7 @@ export const startUpdateEpic: Epic = (action$, state$) => // ROBOTUPDATE_START_UPDATE will set the active updating robot in state const { robotName, systemFile } = action.payload const host = getRobotUpdateRobot(state) - const serverHealth = host?.serverHealth || null + const serverHealth = host?.serverHealth ?? null // we need the target robot's update server to be up to do anything if (host === null || serverHealth === null) { @@ -122,7 +123,7 @@ export const startUpdateEpic: Epic = (action$, state$) => ) } - const capabilities = serverHealth.capabilities || null + const capabilities = serverHealth.capabilities ?? null // if action passed a system file, we need to read that file if (systemFile !== null) { @@ -180,13 +181,13 @@ export const startSessionAfterFileInfoEpic: Epic = (action$, state$) => { withLatestFrom(state$), map<[RobotUpdateFileInfoAction, State], any>(([action, state]) => { const host = getRobotUpdateRobot(state) - const serverHealth = host?.serverHealth || null - const capabilities = serverHealth?.capabilities || null + const serverHealth = host?.serverHealth ?? null + const capabilities = serverHealth?.capabilities ?? null // otherwise robot is ready for migration or update, so get token // capabilities response has the correct request path to use const sessionPath = - capabilities?.buildrootUpdate || - capabilities?.buildrootMigration || + capabilities?.buildrootUpdate ?? + capabilities?.buildrootMigration ?? capabilities?.systemUpdate if (sessionPath == null) { @@ -217,7 +218,9 @@ export const createSessionEpic: Epic = action$ => { const pathPrefix = path.replace('/begin', '') if (ok) { - return of(createSessionSuccess(host, resp.body.token, pathPrefix)) + return of( + createSessionSuccess(host, resp.body.token as string, pathPrefix) + ) } if (!ok && status === 409) { @@ -275,8 +278,8 @@ export const statusPollEpic: Epic = (action$, state$) => { filter(resp => resp.ok), map(successResp => robotUpdateStatus( - successResp.body.stage, - successResp.body.message, + successResp.body.stage as UpdateSessionStage, + successResp.body.message as string, successResp.body.progress != null ? Math.round(successResp.body.progress * 100) : null @@ -297,7 +300,7 @@ const passActiveSession = (props: Partial) => ( return ( robot !== null && - !session?.error && + session?.error == null && every( props, (value, key) => session?.[key as keyof RobotUpdateSession] === value @@ -321,7 +324,7 @@ export const uploadFileEpic: Epic = (_, state$) => { const token: string = session?.token as any const systemFile = session?.fileInfo?.systemFile - return systemFile + return systemFile != null ? uploadRobotUpdateFile(host, `${pathPrefix}/${token}/file`, systemFile) : unexpectedRobotUpdateError(UNABLE_TO_FIND_SYSTEM_FILE) }) @@ -361,7 +364,7 @@ export const restartAfterCommitEpic: Epic = (_, state$) => { ), switchMap>(stateWithSession => { const host: ViewableRobot = getRobotUpdateRobot(stateWithSession) as any - const path = host.serverHealth?.capabilities?.restart || RESTART_PATH + const path = host.serverHealth?.capabilities?.restart ?? RESTART_PATH // @ts-expect-error TODO: host is actually of type Robot|ReachableRobot but this action expects a RobotHost const request$ = fetchRobotApi(host, { method: POST, path }).pipe( switchMap(resp => { @@ -399,7 +402,7 @@ export const finishAfterRestartEpic: Epic = (action$, state$) => { return ( restartDone && robot?.name === action.payload.robotName && - !session?.error && + session?.error == null && session?.step === RESTART ) }), diff --git a/app/src/redux/sessions/epic/createSessionCommandEpic.ts b/app/src/redux/sessions/epic/createSessionCommandEpic.ts index 4f4d62a8e06..461255d5895 100644 --- a/app/src/redux/sessions/epic/createSessionCommandEpic.ts +++ b/app/src/redux/sessions/epic/createSessionCommandEpic.ts @@ -15,11 +15,13 @@ import type { RobotApiRequestOptions, RobotHost, RobotApiResponse, + RobotApiV2ErrorResponseBody, } from '../../robot-api/types' import type { CreateSessionCommandAction, CreateSessionCommandFailureAction, CreateSessionCommandSuccessAction, + SessionResponse, } from '../types' const mapActionToRequest = ( @@ -48,13 +50,13 @@ const mapResponseToAction = ( ? Actions.createSessionCommandSuccess( host.name, originalAction.payload.sessionId, - body, + body as SessionResponse, meta ) : Actions.createSessionCommandFailure( host.name, originalAction.payload.sessionId, - body, + body as RobotApiV2ErrorResponseBody, meta ) } diff --git a/app/src/redux/sessions/epic/createSessionEpic.ts b/app/src/redux/sessions/epic/createSessionEpic.ts index ae8f1719a1b..1ef8edd6c82 100644 --- a/app/src/redux/sessions/epic/createSessionEpic.ts +++ b/app/src/redux/sessions/epic/createSessionEpic.ts @@ -11,8 +11,13 @@ import type { Action, Epic } from '../../types' import type { RobotApiRequestOptions, RobotApiResponse, + RobotApiV2ErrorResponseBody, } from '../../robot-api/types' -import type { CreateSessionAction, EnsureSessionAction } from '../types' +import type { + CreateSessionAction, + EnsureSessionAction, + SessionResponse, +} from '../types' export const mapActionToRequest = ( action: CreateSessionAction | EnsureSessionAction @@ -34,8 +39,12 @@ export const mapResponseToAction = ( const { host, body, ...responseMeta } = response const meta = { ...originalAction.meta, response: responseMeta } return response.ok - ? Actions.createSessionSuccess(host.name, body, meta) - : Actions.createSessionFailure(host.name, body, meta) + ? Actions.createSessionSuccess(host.name, body as SessionResponse, meta) + : Actions.createSessionFailure( + host.name, + body as RobotApiV2ErrorResponseBody, + meta + ) } export const createSessionEpic: Epic = (action$, state$) => { diff --git a/app/src/redux/sessions/epic/deleteSessionEpic.ts b/app/src/redux/sessions/epic/deleteSessionEpic.ts index 40a405c2263..fe854f6f3c0 100644 --- a/app/src/redux/sessions/epic/deleteSessionEpic.ts +++ b/app/src/redux/sessions/epic/deleteSessionEpic.ts @@ -13,7 +13,8 @@ import type { ResponseToActionMapper, } from '../../robot-api/operators' -import type { DeleteSessionAction } from '../types' +import type { DeleteSessionAction, SessionResponse } from '../types' +import type { RobotApiV2ErrorResponseBody } from '../../robot-api/types' const mapActionToRequest: ActionToRequestMapper = action => ({ method: DELETE, @@ -28,11 +29,11 @@ const mapResponseToAction: ResponseToActionMapper = ( const meta = { ...originalAction.meta, response: responseMeta } return response.ok - ? Actions.deleteSessionSuccess(host.name, body, meta) + ? Actions.deleteSessionSuccess(host.name, body as SessionResponse, meta) : Actions.deleteSessionFailure( host.name, originalAction.payload.sessionId, - body, + body as RobotApiV2ErrorResponseBody, meta ) } diff --git a/app/src/redux/sessions/epic/fetchAllSessionsEpic.ts b/app/src/redux/sessions/epic/fetchAllSessionsEpic.ts index 133435df99b..c77a5d0b31a 100644 --- a/app/src/redux/sessions/epic/fetchAllSessionsEpic.ts +++ b/app/src/redux/sessions/epic/fetchAllSessionsEpic.ts @@ -11,8 +11,13 @@ import type { Action, Epic } from '../../types' import type { RobotApiRequestOptions, RobotApiResponse, + RobotApiV2ErrorResponseBody, } from '../../robot-api/types' -import type { FetchAllSessionsAction, EnsureSessionAction } from '../types' +import type { + FetchAllSessionsAction, + EnsureSessionAction, + MultiSessionResponse, +} from '../types' export const mapActionToRequest = (): RobotApiRequestOptions => ({ method: GET, @@ -27,8 +32,16 @@ export const mapResponseToAction = ( const meta = { ...originalAction.meta, response: responseMeta } return response.ok - ? Actions.fetchAllSessionsSuccess(host.name, body, meta) - : Actions.fetchAllSessionsFailure(host.name, body, meta) + ? Actions.fetchAllSessionsSuccess( + host.name, + body as MultiSessionResponse, + meta + ) + : Actions.fetchAllSessionsFailure( + host.name, + body as RobotApiV2ErrorResponseBody, + meta + ) } export const fetchAllSessionsEpic: Epic = (action$, state$) => { diff --git a/app/src/redux/sessions/epic/fetchSessionEpic.ts b/app/src/redux/sessions/epic/fetchSessionEpic.ts index b935929e71d..d9315142ecc 100644 --- a/app/src/redux/sessions/epic/fetchSessionEpic.ts +++ b/app/src/redux/sessions/epic/fetchSessionEpic.ts @@ -9,9 +9,16 @@ import * as Constants from '../constants' import type { Action, Epic } from '../../types' import type { ResponseToActionMapper } from '../../robot-api/operators' -import type { RobotApiRequestOptions } from '../../robot-api/types' +import type { + RobotApiRequestOptions, + RobotApiV2ErrorResponseBody, +} from '../../robot-api/types' -import type { FetchSessionAction, CreateSessionCommandAction } from '../types' +import type { + FetchSessionAction, + CreateSessionCommandAction, + SessionResponse, +} from '../types' export const mapActionToRequest = ( action: FetchSessionAction | CreateSessionCommandAction @@ -28,11 +35,11 @@ const mapResponseToAction: ResponseToActionMapper = ( const meta = { ...originalAction.meta, response: responseMeta } return response.ok - ? Actions.fetchSessionSuccess(host.name, body, meta) + ? Actions.fetchSessionSuccess(host.name, body as SessionResponse, meta) : Actions.fetchSessionFailure( host.name, originalAction.payload.sessionId, - body, + body as RobotApiV2ErrorResponseBody, meta ) } diff --git a/app/src/redux/shell/epic.ts b/app/src/redux/shell/epic.ts index 58a8458b6c5..414000cef39 100644 --- a/app/src/redux/shell/epic.ts +++ b/app/src/redux/shell/epic.ts @@ -15,6 +15,7 @@ import { getUpdateChannel } from '../config' import { getAvailableShellUpdate, checkShellUpdate } from './update' import { remote } from './remote' +import type { OperatorFunction } from 'rxjs' import type { Epic, Action } from '../types' const { ipcRenderer } = remote @@ -24,11 +25,11 @@ const log = createLogger(new URL('', import.meta.url).pathname) const sendActionToShellEpic: Epic = action$ => action$.pipe( // @ts-expect-error protect against absent meta key on action - filter(a => a.meta != null && a.meta.shell != null && a.meta.shell), + filter(a => a.meta?.shell != null && a.meta.shell), tap((shellAction: Action) => { ipcRenderer.send('dispatch', shellAction) }), - ignoreElements() + ignoreElements() as OperatorFunction ) const receiveActionFromShellEpic: Epic = () => diff --git a/app/src/redux/store.ts b/app/src/redux/store.ts index c273950bc50..0567386b313 100644 --- a/app/src/redux/store.ts +++ b/app/src/redux/store.ts @@ -7,21 +7,25 @@ import { createEpicMiddleware } from 'redux-observable' import { rootReducer, history } from './reducer' import { rootEpic } from './epic' -import type { Action, State } from './types' +import type { StoreEnhancer } from 'redux' +import type { Action, Middleware, State } from './types' const epicMiddleware = createEpicMiddleware() const middleware = applyMiddleware( thunk, epicMiddleware, - routerMiddleware(history) + routerMiddleware(history) as Middleware ) const composeEnhancers = - ((window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ && - (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({ maxAge: 200 })) || + (window as any)?.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__?.({ maxAge: 200 }) ?? compose -export const store = createStore(rootReducer, composeEnhancers(middleware)) + +export const store = createStore( + rootReducer, + composeEnhancers(middleware) as StoreEnhancer +) epicMiddleware.run(rootEpic) diff --git a/components/src/forms/RadioGroup.stories.tsx b/components/src/forms/RadioGroup.stories.tsx index 696adcfb60f..13578207332 100644 --- a/components/src/forms/RadioGroup.stories.tsx +++ b/components/src/forms/RadioGroup.stories.tsx @@ -20,8 +20,8 @@ const Template: Story> = ({ onChange, ...args }) => { - const [controlledValue, setControlledValue] = React.useState( - args.options[0].value + const [controlledValue, setControlledValue] = React.useState( + args?.options?.[0] != null ? args.options[0].value : '' ) return ( @@ -29,7 +29,9 @@ const Template: Story> = ({ {...args} value={controlledValue} onChange={e => { - setControlledValue(e.target.value) + setControlledValue( + 'value' in e.target ? (e.target.value as string) : '' + ) }} /> diff --git a/components/src/primitives/style-props.ts b/components/src/primitives/style-props.ts index 2140866eda7..b7de00e2513 100644 --- a/components/src/primitives/style-props.ts +++ b/components/src/primitives/style-props.ts @@ -193,4 +193,4 @@ export const styleProps = (props: Types.StyleProps): CSSObject => ({ }) export const isntStyleProp = (prop: string | React.ReactText): boolean => - !STYLE_PROPS.includes(prop as any) + !STYLE_PROPS.includes(prop as typeof STYLE_PROPS[number]) diff --git a/labware-designer/src/organisms/CreateLabwareSandbox/index.tsx b/labware-designer/src/organisms/CreateLabwareSandbox/index.tsx index 902600dfd71..e2118b07c57 100644 --- a/labware-designer/src/organisms/CreateLabwareSandbox/index.tsx +++ b/labware-designer/src/organisms/CreateLabwareSandbox/index.tsx @@ -27,7 +27,12 @@ import { import { IRREGULAR_OPTIONS, REGULAR_OPTIONS } from './fixtures' -import type { DeckDefinition, LabwareDefinition2 } from '@opentrons/shared-data' +import type { + DeckDefinition, + IrregularLabwareProps, + LabwareDefinition2, + RegularLabwareProps, +} from '@opentrons/shared-data' const SLOT_OPTIONS = ot2StandardDeckV4.locations.addressableAreas.map( slot => slot.id @@ -93,7 +98,12 @@ export function CreateLabwareSandbox(): JSX.Element { ? createRegularLabware : createIrregularLabware try { - setLabwareToRender(createLabware(JSON.parse(event.target.value))) + setLabwareToRender( + createLabware( + JSON.parse(event.target.value) as IrregularLabwareProps & + RegularLabwareProps + ) + ) } catch (error) { console.log('Failed to parse options as JSON', error) } diff --git a/labware-library/src/analytics/utils.ts b/labware-library/src/analytics/utils.ts index 6b7e11e31aa..0af874a4d83 100644 --- a/labware-library/src/analytics/utils.ts +++ b/labware-library/src/analytics/utils.ts @@ -19,10 +19,9 @@ const persistAnalyticsCookie = (cookies: AnalyticsState): void => { } const getAnalyticsCookie = (): AnalyticsState => { - const cookies = cookie.parse((global as any).document.cookie) - const analyticsCookie = cookies[COOKIE_KEY_NAME] - ? JSON.parse(cookies[COOKIE_KEY_NAME]) - : {} + const cookies = cookie.parse((global as any).document.cookie as string) + const analyticsCookie = + cookies[COOKIE_KEY_NAME] != null ? JSON.parse(cookies[COOKIE_KEY_NAME]) : {} return analyticsCookie } diff --git a/labware-library/src/labware-creator/components/Dropdown.tsx b/labware-library/src/labware-creator/components/Dropdown.tsx index a4ea2c8101a..02693488d2b 100644 --- a/labware-library/src/labware-creator/components/Dropdown.tsx +++ b/labware-library/src/labware-creator/components/Dropdown.tsx @@ -66,7 +66,10 @@ export const Dropdown = (props: DropdownProps): JSX.Element => { {/* @ts-expect-error(IL, 2021-03-24): formik types need cleanup w LabwareFields */} {({ field, form }) => ( - {getLabel(field.name, form.values)} + {getLabel( + field.name as keyof LabwareFields, + form.values as LabwareFields + )} ( {/* @ts-expect-error(IL, 2021-03-24): formik types need cleanup w LabwareFields */} {({ form, field }) => - getIsHidden(props.name, form.values) ? null : ( + getIsHidden(props.name, form.values as LabwareFields) ? null : (

- {getLabel(props.name, form.values)} + {getLabel(props.name, form.values as LabwareFields)}
{ const { label, caption, placeholder, units } = props - const inputMasks = props.inputMasks || [] + const inputMasks = props.inputMasks ?? [] // @ts-expect-error(IL, 2021-03-24): formik types need cleanup w LabwareFields const makeHandleChange = ({ field, form }) => ( e: React.FormEvent @@ -31,7 +31,7 @@ export const TextField = (props: Props): JSX.Element => { const prevValue = field.value const rawValue = e.currentTarget.value const nextValue = inputMasks.reduce( - (acc, maskFn) => maskFn(prevValue, acc), + (acc, maskFn) => maskFn(prevValue as string, acc), rawValue ) form.setFieldValue(props.name, nextValue) @@ -40,10 +40,10 @@ export const TextField = (props: Props): JSX.Element => { return ( {({ field, form }: FieldProps) => - getIsHidden(props.name, form.values) ? null : ( + getIsHidden(props.name, form.values as LabwareFields) ? null : (