Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

first round of updates to disable type assertions #2879

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
3 changes: 2 additions & 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 All @@ -18,6 +18,7 @@ const isAxiosErrorWithResponseMessage = (
error?: Error | AxiosError,
): error is AxiosError<{ message: string }> =>
Boolean(
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
error && typeof (error as AxiosError<{ message: string }>).response?.data.message === 'string',
);

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
36 changes: 23 additions & 13 deletions frontend/src/api/prometheus/serving.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { RefreshIntervalValue } from '~/concepts/metrics/const';
import useRefreshInterval from '~/utilities/useRefreshInterval';
import { SupportedArea, useIsAreaAvailable } from '~/concepts/areas';
import { PROMETHEUS_BIAS_PATH } from '~/api/prometheus/const';
import { EitherNotBoth } from '~/typeHelpers';
import useQueryRangeResourceData from './useQueryRangeResourceData';
import {
defaultResponsePredicate,
Expand All @@ -22,17 +23,26 @@ import {

export const useModelServingMetrics = (
type: PerformanceMetricType,
queries: { [key in ModelMetricType]: string } | { [key in ServerMetricType]: string },
queries: EitherNotBoth<
{ [key in ModelMetricType]: string },
{ [key in ServerMetricType]: string }
>,
timeframe: TimeframeTitle,
lastUpdateTime: number,
setLastUpdateTime: (time: number) => void,
refreshInterval: RefreshIntervalTitle,
namespace: string,
): {
data: Record<
ServerMetricType | ModelMetricType,
ContextResourceData<PrometheusQueryRangeResultValue | PrometheusQueryRangeResponseDataResult>
>;
data: {
[ServerMetricType.REQUEST_COUNT]: ContextResourceData<PrometheusQueryRangeResultValue>;
[ServerMetricType.AVG_RESPONSE_TIME]: ContextResourceData<PrometheusQueryRangeResponseDataResult>;
[ServerMetricType.CPU_UTILIZATION]: ContextResourceData<PrometheusQueryRangeResultValue>;
[ServerMetricType.MEMORY_UTILIZATION]: ContextResourceData<PrometheusQueryRangeResultValue>;
[ModelMetricType.REQUEST_COUNT_FAILED]: ContextResourceData<PrometheusQueryRangeResultValue>;
[ModelMetricType.REQUEST_COUNT_SUCCESS]: ContextResourceData<PrometheusQueryRangeResultValue>;
[ModelMetricType.TRUSTY_AI_SPD]: ContextResourceData<PrometheusQueryRangeResponseDataResult>;
[ModelMetricType.TRUSTY_AI_DIR]: ContextResourceData<PrometheusQueryRangeResponseDataResult>;
};
refresh: () => void;
} => {
const [end, setEnd] = React.useState(lastUpdateTime);
Expand All @@ -43,7 +53,7 @@ export const useModelServingMetrics = (

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

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

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

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

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

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

const modelTrustyAIDIR = useQueryRangeResourceData(
biasMetricsAreaAvailable && type === PerformanceMetricType.MODEL,
(queries as { [key in ModelMetricType]: string })[ModelMetricType.TRUSTY_AI_DIR],
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);
4 changes: 2 additions & 2 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) ?? OdhDocumentType.Documentation;
const docName = odhDoc.metadata.name;
const duration = odhDoc.spec.durationMinutes;

Expand Down
12 changes: 6 additions & 6 deletions frontend/src/components/FilterSidePanelCategoryItem.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import * as React from 'react';
import { css } from '@patternfly/react-styles';
import { Checkbox } from '@patternfly/react-core';
import { Checkbox, CheckboxProps } from '@patternfly/react-core';

export interface FilterSidePanelCategoryItemProps extends React.HTMLProps<HTMLDivElement> {
export interface FilterSidePanelCategoryItemProps {
id: string;
/** Children nodes */
children: React.ReactNode;
Expand All @@ -13,7 +13,7 @@ export interface FilterSidePanelCategoryItemProps extends React.HTMLProps<HTMLDi
/** Optional count of the items matching the filter */
count?: number | null;
/** Callback for a click on the Filter Item Checkbox */
onClick?: (event: React.SyntheticEvent<HTMLElement>) => void;
onChange?: CheckboxProps['onChange'];
/** Flag to show if the Filter Item Checkbox is checked. */
checked?: boolean;
/** Title of the checkbox */
Expand All @@ -27,7 +27,7 @@ const FilterSidePanelCategoryItem: React.FunctionComponent<FilterSidePanelCatego
className = '',
icon = null,
count = null,
onClick,
onChange,
checked = false,
title = '',
...props
Expand All @@ -43,8 +43,8 @@ const FilterSidePanelCategoryItem: React.FunctionComponent<FilterSidePanelCatego
return (
<div id={id} className={classes} {...props}>
<Checkbox
onClick={onClick}
checked={checked}
onChange={onChange}
isChecked={checked}
data-testid={id}
id={`${id}--check-box`}
label={label}
Expand Down
5 changes: 3 additions & 2 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,7 +26,8 @@ const OdhDocListItem: React.FC<OdhDocCardProps> = ({ odhDoc, favorite, updateFav
};

const renderTypeBadge = () => {
const docType = odhDoc.spec.type as OdhDocumentType;
const docType =
asEnumMember(odhDoc.spec.type, OdhDocumentType) ?? OdhDocumentType.Documentation;
const typeBadgeClasses = classNames('odh-list-item__partner-badge odh-m-doc', {
'odh-m-documentation': docType === OdhDocumentType.Documentation,
'odh-m-tutorial': docType === OdhDocumentType.Tutorial,
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
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export const useBrowserStorage = <T,>(
[isSessionStorage, jsonify, setJSONValue, setStringValue, storageKey],
);

// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
return [(getValue(storageKey, jsonify, isSessionStorage) as T) ?? defaultValue, setValue];
};

Expand Down
2 changes: 2 additions & 0 deletions frontend/src/components/table/useTableColumnSort.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,9 @@ const useTableColumnSort = <T>(
return 0;
}

// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const dataValueA = a[columnField.field as keyof T];
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const dataValueB = b[columnField.field as keyof T];
if (typeof dataValueA === 'string' && typeof dataValueB === 'string') {
return dataValueA.localeCompare(dataValueB);
Expand Down
3 changes: 1 addition & 2 deletions frontend/src/concepts/areas/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ const getFlags = (dashboardConfigSpec: DashboardConfigKind['spec']): FlagState =
typeof value === 'boolean';

return {
...Object.keys(flags).reduce<FlagState>((acc, key) => {
const value = flags[key as FeatureFlag];
...Object.entries(flags).reduce<FlagState>((acc, [key, value]) => {
if (isFeatureFlag(key, value)) {
acc[key] = key.startsWith('disable') ? !value : value;
}
Expand Down
6 changes: 5 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,10 @@ const DashboardSearchField: React.FC<DashboardSearchFieldProps> = ({
}))}
value={searchType}
onChange={(key) => {
onSearchTypeChange(key as SearchType);
const enumMember = asEnumMember(key, SearchType);
if (enumMember !== null) {
onSearchTypeChange(enumMember);
}
}}
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
1 change: 1 addition & 0 deletions frontend/src/concepts/docResources/docUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export const getQuickStartDocs = (
// Get doc cards for the quick starts
const docs: OdhDocument[] = quickStarts.map(
(quickStart) =>
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
_.merge({}, quickStart, {
spec: {
type: OdhDocumentType.QuickStart,
Expand Down
Loading
Loading