Skip to content

Commit

Permalink
first round of updates to disable type assertions
Browse files Browse the repository at this point in the history
  • Loading branch information
rsun19 committed Jun 6, 2024
1 parent 78b9cd9 commit 8011609
Show file tree
Hide file tree
Showing 60 changed files with 266 additions and 153 deletions.
12 changes: 12 additions & 0 deletions frontend/.eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,18 @@
}
]
}
},
{
"files": ["*.ts", "*.tsx"],
"excludedFiles": ["**/__mocks__/**", "**/__tests__/**"],
"rules": {
"@typescript-eslint/consistent-type-assertions": [
"error",
{
"assertionStyle": "never"
}
]
}
}
]
}
7 changes: 3 additions & 4 deletions frontend/src/__tests__/unit/testUtils/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ export const renderHook = <
options?: RenderHookOptions<Props, Q, Container, BaseElement>,
): RenderHookResultExt<Result, Props> => {
let updateCount = 0;
let prevResult: Result | undefined;
let currentResult: Result | undefined;
let prevResult: Result;
let currentResult: Result;

const renderResult = renderHookRTL((props) => {
updateCount++;
Expand All @@ -80,8 +80,7 @@ export const renderHook = <
const renderResultExt: RenderHookResultExt<Result, Props> = {
...renderResult,

getPreviousResult: () =>
updateCount > 1 ? (prevResult as Result) : renderResult.result.current,
getPreviousResult: () => (updateCount > 1 ? prevResult : renderResult.result.current),

getUpdateCount: () => updateCount,

Expand Down
2 changes: 1 addition & 1 deletion frontend/src/api/errorUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { K8sStatus } from '@openshift/dynamic-plugin-sdk-utils';
import { AxiosError } from 'axios';

export const isK8sStatus = (data: unknown): data is K8sStatus =>
(data as K8sStatus).kind === 'Status';
typeof data === 'object' && data !== null && 'kind' in data && data.kind === 'Status';

export class K8sStatusError extends Error {
public statusObject: K8sStatus;
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/api/modelRegistry/errorUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { ModelRegistryError } from '~/concepts/modelRegistry/types';
import { isCommonStateError } from '~/utilities/useFetchState';

const isError = (e: unknown): e is ModelRegistryError =>
['code', 'message'].every((key) => key in (e as ModelRegistryError));
typeof e === 'object' && e !== null && ['code', 'message'].every((key) => key in e);

export const handleModelRegistryFailures = <T>(promise: Promise<T>): Promise<T> =>
promise
Expand Down
6 changes: 4 additions & 2 deletions frontend/src/api/pipelines/errorUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ type ResultErrorKF = {
};

const isErrorKF = (e: unknown): e is ErrorKF =>
['error', 'code', 'message'].every((key) => key in (e as ErrorKF));
typeof e === 'object' && e !== null && ['error', 'code', 'message'].every((key) => key in e);

const isErrorDetailsKF = (result: unknown): result is ResultErrorKF =>
['error_details', 'error_message'].every((key) => key in (result as ResultErrorKF));
typeof result === 'object' &&
result !== null &&
['error_details', 'error_message'].every((key) => key in result);

export const handlePipelineFailures = <T>(promise: Promise<T>): Promise<T> =>
promise
Expand Down
24 changes: 16 additions & 8 deletions frontend/src/api/prometheus/serving.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export const useModelServingMetrics = (

const serverRequestCount = useQueryRangeResourceData(
performanceMetricsAreaAvailable && type === PerformanceMetricType.SERVER,
(queries as { [key in ServerMetricType]: string })[ServerMetricType.REQUEST_COUNT],
ServerMetricType.REQUEST_COUNT in queries ? queries[ServerMetricType.REQUEST_COUNT] : '',
end,
timeframe,
defaultResponsePredicate,
Expand All @@ -53,7 +53,9 @@ export const useModelServingMetrics = (
const serverAverageResponseTime =
useQueryRangeResourceData<PrometheusQueryRangeResponseDataResult>(
performanceMetricsAreaAvailable && type === PerformanceMetricType.SERVER,
(queries as { [key in ServerMetricType]: string })[ServerMetricType.AVG_RESPONSE_TIME],
ServerMetricType.AVG_RESPONSE_TIME in queries
? queries[ServerMetricType.AVG_RESPONSE_TIME]
: '',
end,
timeframe,
prometheusQueryRangeResponsePredicate,
Expand All @@ -62,7 +64,7 @@ export const useModelServingMetrics = (

const serverCPUUtilization = useQueryRangeResourceData(
performanceMetricsAreaAvailable && type === PerformanceMetricType.SERVER,
(queries as { [key in ServerMetricType]: string })[ServerMetricType.CPU_UTILIZATION],
ServerMetricType.CPU_UTILIZATION in queries ? queries[ServerMetricType.CPU_UTILIZATION] : '',
end,
timeframe,
defaultResponsePredicate,
Expand All @@ -71,7 +73,9 @@ export const useModelServingMetrics = (

const serverMemoryUtilization = useQueryRangeResourceData(
performanceMetricsAreaAvailable && type === PerformanceMetricType.SERVER,
(queries as { [key in ServerMetricType]: string })[ServerMetricType.MEMORY_UTILIZATION],
ServerMetricType.MEMORY_UTILIZATION in queries
? queries[ServerMetricType.MEMORY_UTILIZATION]
: '',
end,
timeframe,
defaultResponsePredicate,
Expand All @@ -80,7 +84,9 @@ export const useModelServingMetrics = (

const modelRequestSuccessCount = useQueryRangeResourceData(
performanceMetricsAreaAvailable && type === PerformanceMetricType.MODEL,
(queries as { [key in ModelMetricType]: string })[ModelMetricType.REQUEST_COUNT_SUCCESS],
ModelMetricType.REQUEST_COUNT_SUCCESS in queries
? queries[ModelMetricType.REQUEST_COUNT_SUCCESS]
: '',
end,
timeframe,
defaultResponsePredicate,
Expand All @@ -89,7 +95,9 @@ export const useModelServingMetrics = (

const modelRequestFailedCount = useQueryRangeResourceData(
performanceMetricsAreaAvailable && type === PerformanceMetricType.MODEL,
(queries as { [key in ModelMetricType]: string })[ModelMetricType.REQUEST_COUNT_FAILED],
ModelMetricType.REQUEST_COUNT_FAILED in queries
? queries[ModelMetricType.REQUEST_COUNT_FAILED]
: '',
end,
timeframe,
defaultResponsePredicate,
Expand All @@ -98,7 +106,7 @@ export const useModelServingMetrics = (

const modelTrustyAISPD = useQueryRangeResourceData(
biasMetricsAreaAvailable && type === PerformanceMetricType.MODEL,
(queries as { [key in ModelMetricType]: string })[ModelMetricType.TRUSTY_AI_SPD],
ModelMetricType.TRUSTY_AI_SPD in queries ? queries[ModelMetricType.TRUSTY_AI_SPD] : '',
end,
timeframe,
prometheusQueryRangeResponsePredicate,
Expand All @@ -108,7 +116,7 @@ export const useModelServingMetrics = (

const modelTrustyAIDIR = useQueryRangeResourceData(
biasMetricsAreaAvailable && type === PerformanceMetricType.MODEL,
(queries as { [key in ModelMetricType]: string })[ModelMetricType.TRUSTY_AI_DIR],
ModelMetricType.TRUSTY_AI_DIR in queries ? queries[ModelMetricType.TRUSTY_AI_DIR] : '',
end,
timeframe,
prometheusQueryRangeResponsePredicate,
Expand Down
3 changes: 1 addition & 2 deletions frontend/src/api/trustyai/errorUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ type TrustyAIClientErrorViolation = {
};

const isTrustyAIClientError = (e: unknown): e is TrustyAIClientError =>
typeof e === 'object' &&
['title', 'status', 'violations'].every((key) => key in (e as TrustyAIClientError));
typeof e === 'object' && e !== null && ['title', 'status', 'violations'].every((key) => key in e);

export const handleTrustyAIFailures = <T>(promise: Promise<T>): Promise<T> =>
promise.then((result) => {
Expand Down
10 changes: 2 additions & 8 deletions frontend/src/app/AppContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,7 @@ type AppContextProps = {
storageClasses: StorageClassKind[];
};

const defaultAppContext: AppContextProps = {
buildStatuses: [],
// At runtime dashboardConfig is never null -- DO NOT DO THIS usually
dashboardConfig: null as unknown as DashboardConfigKind,
storageClasses: [] as StorageClassKind[],
};

export const AppContext = React.createContext(defaultAppContext);
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
export const AppContext = React.createContext({} as AppContextProps);

export const useAppContext = (): AppContextProps => React.useContext(AppContext);
63 changes: 33 additions & 30 deletions frontend/src/components/DocCardBadges.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { QuickStartContext, QuickStartContextValues } from '@patternfly/quicksta
import { OdhDocument, OdhDocumentType } from '~/types';
import { getQuickStartCompletionStatus, CompletionStatusEnum } from '~/utilities/quickStartUtils';
import { DOC_TYPE_TOOLTIPS } from '~/utilities/const';
import { getLabelColorForDocType, getDuration } from '~/utilities/utils';
import { getLabelColorForDocType, getDuration, asEnumMember } from '~/utilities/utils';
import { DOC_TYPE_LABEL } from '~/pages/learningCenter/const';

import './OdhCard.scss';
Expand All @@ -19,7 +19,7 @@ const DocCardBadges: React.FC<DocCardBadgesProps> = ({ odhDoc }) => {
const [completionStatus, setCompletionStatus] = React.useState<
CompletionStatusEnum | undefined
>();
const docType = odhDoc.spec.type as OdhDocumentType;
const docType = asEnumMember(odhDoc.spec.type, OdhDocumentType);
const docName = odhDoc.metadata.name;
const duration = odhDoc.spec.durationMinutes;

Expand All @@ -32,35 +32,38 @@ const DocCardBadges: React.FC<DocCardBadgesProps> = ({ odhDoc }) => {
}
}, [qsContext, docType, docName]);

const label = DOC_TYPE_LABEL[docType] || 'Documentation';
if (docType !== null) {
const label = DOC_TYPE_LABEL[docType] || 'Documentation';

return (
<LabelGroup defaultIsOpen numLabels={3}>
<Tooltip content={DOC_TYPE_TOOLTIPS[docType]}>
<Label color={getLabelColorForDocType(docType)}>{label}</Label>
</Tooltip>
{duration ? (
<Label variant="outline" color="grey">
{getDuration(duration)}
</Label>
) : null}
{completionStatus === CompletionStatusEnum.InProgress ? (
<Label variant="outline" color="purple" icon={<SyncAltIcon />}>
In Progress
</Label>
) : null}
{completionStatus === CompletionStatusEnum.Success ? (
<Label variant="outline" color="green" icon={<CheckCircleIcon />}>
Complete
</Label>
) : null}
{completionStatus === CompletionStatusEnum.Failed ? (
<Label variant="outline" color="red" icon={<ExclamationCircleIcon />}>
Failed
</Label>
) : null}
</LabelGroup>
);
return (
<LabelGroup defaultIsOpen numLabels={3}>
<Tooltip content={DOC_TYPE_TOOLTIPS[docType]}>
<Label color={getLabelColorForDocType(docType)}>{label}</Label>
</Tooltip>
{duration ? (
<Label variant="outline" color="grey">
{getDuration(duration)}
</Label>
) : null}
{completionStatus === CompletionStatusEnum.InProgress ? (
<Label variant="outline" color="purple" icon={<SyncAltIcon />}>
In Progress
</Label>
) : null}
{completionStatus === CompletionStatusEnum.Success ? (
<Label variant="outline" color="green" icon={<CheckCircleIcon />}>
Complete
</Label>
) : null}
{completionStatus === CompletionStatusEnum.Failed ? (
<Label variant="outline" color="red" icon={<ExclamationCircleIcon />}>
Failed
</Label>
) : null}
</LabelGroup>
);
}
return null;
};

export default DocCardBadges;
29 changes: 16 additions & 13 deletions frontend/src/components/OdhDocListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ExternalLinkAltIcon } from '@patternfly/react-icons';
import { OdhDocument, OdhDocumentType } from '~/types';
import { getQuickStartLabel, launchQuickStart } from '~/utilities/quickStartUtils';
import { DOC_TYPE_TOOLTIPS } from '~/utilities/const';
import { getDuration } from '~/utilities/utils';
import { asEnumMember, getDuration } from '~/utilities/utils';
import { useQuickStartCardSelected } from './useQuickStartCardSelected';
import FavoriteButton from './FavoriteButton';

Expand All @@ -26,18 +26,21 @@ const OdhDocListItem: React.FC<OdhDocCardProps> = ({ odhDoc, favorite, updateFav
};

const renderTypeBadge = () => {
const docType = odhDoc.spec.type as OdhDocumentType;
const typeBadgeClasses = classNames('odh-list-item__partner-badge odh-m-doc', {
'odh-m-documentation': docType === OdhDocumentType.Documentation,
'odh-m-tutorial': docType === OdhDocumentType.Tutorial,
'odh-m-quick-start': docType === OdhDocumentType.QuickStart,
'odh-m-how-to': docType === OdhDocumentType.HowTo,
});
return (
<Tooltip content={DOC_TYPE_TOOLTIPS[docType]}>
<div className={typeBadgeClasses}>{odhDoc.spec.type}</div>
</Tooltip>
);
const docType = asEnumMember(odhDoc.spec.type, OdhDocumentType);
if (docType !== null) {
const typeBadgeClasses = classNames('odh-list-item__partner-badge odh-m-doc', {
'odh-m-documentation': docType === OdhDocumentType.Documentation,
'odh-m-tutorial': docType === OdhDocumentType.Tutorial,
'odh-m-quick-start': docType === OdhDocumentType.QuickStart,
'odh-m-how-to': docType === OdhDocumentType.HowTo,
});
return (
<Tooltip content={DOC_TYPE_TOOLTIPS[docType]}>
<div className={typeBadgeClasses}>{odhDoc.spec.type}</div>
</Tooltip>
);
}
return null;
};

const renderDocLink = () => {
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/components/ToastNotification.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Alert, AlertActionCloseButton, AlertVariant } from '@patternfly/react-c
import { AppNotification } from '~/redux/types';
import { ackNotification, hideNotification } from '~/redux/actions/actions';
import { useAppDispatch } from '~/redux/hooks';
import { asEnumMember } from '~/utilities/utils';

const TOAST_NOTIFICATION_TIMEOUT = 8 * 1000;

Expand Down Expand Up @@ -36,7 +37,7 @@ const ToastNotification: React.FC<ToastNotificationProps> = ({ notification }) =

return (
<Alert
variant={notification.status as AlertVariant}
variant={asEnumMember(notification.status, AlertVariant) ?? undefined}
title={notification.title}
actionClose={
<AlertActionCloseButton onClose={() => dispatch(ackNotification(notification))} />
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/concepts/dashboard/DashboardSearchField.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as React from 'react';
import { InputGroup, SearchInput, InputGroupItem } from '@patternfly/react-core';
import SimpleDropdownSelect from '~/components/SimpleDropdownSelect';
import { asEnumMember } from '~/utilities/utils';

// List all the possible search fields here
export enum SearchType {
Expand Down Expand Up @@ -48,7 +49,7 @@ const DashboardSearchField: React.FC<DashboardSearchFieldProps> = ({
}))}
value={searchType}
onChange={(key) => {
onSearchTypeChange(key as SearchType);
onSearchTypeChange(asEnumMember(key, SearchType)!);
}}
icon={icon}
/>
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/concepts/distributedWorkloads/utils.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
convertToUnit,
} from '~/utilities/valueUnits';
import { WorkloadWithUsage } from '~/api';
import { isEnumMember } from '~/utilities/utils';

export enum WorkloadStatusType {
Pending = 'Pending',
Expand Down Expand Up @@ -166,7 +167,7 @@ export const getWorkloadName = (workload: WorkloadKind): string =>
workload.metadata?.name || 'Unnamed';

export const isKnownWorkloadOwnerType = (s: string): s is WorkloadOwnerType =>
(Object.values(WorkloadOwnerType) as string[]).includes(s);
isEnumMember(s, WorkloadOwnerType);

export const getWorkloadOwner = (
workload: WorkloadKind,
Expand Down
7 changes: 5 additions & 2 deletions frontend/src/concepts/metrics/utils.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { SelectOptionObject } from '@patternfly/react-core/deprecated';
import { TimeframeTitle, RefreshIntervalTitle } from '~/concepts/metrics/types';
import { asEnumMember } from '~/utilities/utils';

export const isTimeframeTitle = (
timeframe: string | SelectOptionObject,
): timeframe is TimeframeTitle =>
Object.values(TimeframeTitle).includes(timeframe as TimeframeTitle);
Object.values(TimeframeTitle).includes(asEnumMember(timeframe.toString(), TimeframeTitle)!);

export const isRefreshIntervalTitle = (
refreshInterval: string | SelectOptionObject,
): refreshInterval is RefreshIntervalTitle =>
Object.values(RefreshIntervalTitle).includes(refreshInterval as RefreshIntervalTitle);
Object.values(RefreshIntervalTitle).includes(
asEnumMember(refreshInterval.toString(), RefreshIntervalTitle)!,
);
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export const ModelRegistryContext = React.createContext<ModelRegistryContextType
hasCR: false,
crInitializing: false,
serverTimedOut: false,
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
apiState: { apiAvailable: false, api: null as unknown as ModelRegistryAPIState['api'] },
ignoreTimedOut: () => undefined,
refreshState: async () => undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,10 @@ const PipelineAndVersionContextProvider: React.FC<PipelineAndVersionContextProvi
}),
getResourcesForDeletion: () => ({
pipelines: selectedPipelines,
versions: (Object.values(selectedVersions) as SelectedVersion[])
versions: Object.values(selectedVersions)
.map((selectedVersion) =>
selectedVersion.versions.map((version) => ({
pipelineName: selectedVersion.pipelineName,
selectedVersion!.versions.map((version) => ({
pipelineName: selectedVersion!.pipelineName,
version,
})),
)
Expand Down
Loading

0 comments on commit 8011609

Please sign in to comment.