Skip to content

Commit

Permalink
[react@18] More breaking type fixes (should be the last pr) (elastic#…
Browse files Browse the repository at this point in the history
…192266)

## Summary

Part of elastic#138222

in @types/react@18 types
DefinitelyTyped/DefinitelyTyped#56210. This PR
addresses a bunch of remaining fixes **(hopefully the last mass ping PR
like this)** The most common are:


### 1 Objects are no longer considered a valid ReactNode

In types@17 the ReactNode typing was too soft, it allowed objects and
functions being passed as ReactNode, e.g.

```
let obj: React.ReactNode = {};
let func: React.ReactNode = () => {};
```

This was by mistake, and this PR mutes most of such cases by simply
casting to a `string` or `ReactNode`.
In some cases, it is worth to follow up and address the raised issues in
a better way (see in comments)


```diff

function MyComponent() {

const error: string | Error = 'Error'

return (
  <div>
-   {error}
+   {error as string}
  </div>
)

}

```


Most common problems are related to rendering errors, where it could be
`string | Error` object rendered directly as a ReactNode. Most often it
is related to alerting framework:

```
export interface RuleFormParamsErrors {
  [key: string]: string | string[] | RuleFormParamsErrors;
}
```

Not sure if there is a better fix then casting, surely not short-term. 

### 2 More `useCallback` implicit any fixes

Follow up to elastic#191659

### 3 `EuiSelect` doesn't have a placeholder prop 

In a couple of places, the `placeholder` prop was removed. This is
because react types were updated and `placeholder` was removed from the
base HTML element, so it highlighted places where `placeholder` prop was
redundant
  • Loading branch information
Dosant authored and gergoabraham committed Sep 13, 2024
1 parent ed68d72 commit c30aeea
Show file tree
Hide file tree
Showing 162 changed files with 293 additions and 277 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export const Todos = () => {
deleteTodoMutation.isLoading ||
updateTodoMutation.isLoading;

if (isError) return <p>Error: {error}</p>;
if (isError) return <p>Error: {error as string}</p>;

return (
<>
Expand Down
2 changes: 1 addition & 1 deletion examples/routing_example/public/random_number_example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export function RandomNumberRouteExample({ fetchRandomNumber }: Props) {

{error !== undefined ? (
<EuiCallOut color="danger" iconType="warning">
{error}
{JSON.stringify(error)}
</EuiCallOut>
) : null}
{randomNumber > -1 ? (
Expand Down
6 changes: 4 additions & 2 deletions examples/search_examples/public/search/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ export const SearchExamplesApp = ({
const executedAt = (res as IMyStrategyResponse).executed_at;
const message = (
<EuiText>
Searched {res.rawResponse.hits.total} documents. <br />
Searched {res.rawResponse.hits.total as number} documents. <br />
The ${metricAggType} of {selectedNumericField!.name} is{' '}
{aggResult ? Math.floor(aggResult) : 0}.
<br />
Expand Down Expand Up @@ -331,7 +331,9 @@ export const SearchExamplesApp = ({
setWarningContents(warnings);
}

const message = <EuiText>Searched {result.rawResponse.hits.total} documents.</EuiText>;
const message = (
<EuiText>Searched {result.rawResponse.hits.total as number} documents.</EuiText>
);
notifications.toasts.addSuccess(
{
title: 'Query result',
Expand Down
2 changes: 1 addition & 1 deletion examples/search_examples/public/search_sessions/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,7 @@ function doSearch(
const message = (
<KibanaRenderContextProvider {...startServices}>
<EuiText>
Searched {res.rawResponse.hits.total} documents. <br />
Searched {res.rawResponse.hits.total as number} documents. <br />
The average of {numericFieldName} is {avgResult ? Math.floor(avgResult) : 0}
.
<br />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export const LogLevelBadge = ({
data-test-subj={`${dataTestSubj}-unknown`}
css={badgeCss}
>
{logLevel}
{logLevel as React.ReactNode}
</EuiBadge>
);
}
Expand All @@ -53,7 +53,7 @@ export const LogLevelBadge = ({
data-test-subj={`${dataTestSubj}-${coalescedValue}`}
css={badgeCss}
>
{logLevel}
{logLevel as React.ReactNode}
</EuiBadge>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ export const UnifiedFieldListSidebarComponent: React.FC<UnifiedFieldListSidebarP
);
const onSupportedFieldFilter: GroupedFieldsParams<DataViewField>['onSupportedFieldFilter'] =
useCallback(
(field) => {
(field: DataViewField) => {
return shouldShowField(
field,
searchMode,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ export function FilterQueryInput({
}
)}
>
{inputFilter?.query ||
{(inputFilter?.query as string) ||
i18n.translate(
'visualizationUiComponents.filterQueryInput.emptyFilterQuery',
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3199,7 +3199,7 @@ describe('XYChart component', () => {
// styles are passed because they are shared, dataValues is rounded to the interval
expect(groupedAnnotation).toMatchSnapshot();
// renders numeric icon for grouped annotations
const marker = mount(<div>{groupedAnnotation.prop('marker')}</div>);
const marker = mount(<div>{groupedAnnotation.prop('marker') as React.ReactNode}</div>);
const numberIcon = marker.find('NumberIcon');
expect(numberIcon.length).toEqual(1);
expect(numberIcon.text()).toEqual('3');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ export const useDashboardListingTable = ({
}
}, [hasInitialFetchReturned]);

const getDetailViewLink: GetDetailViewLink = useCallback(
const getDetailViewLink = useCallback<NonNullable<GetDetailViewLink>>(
({ id, attributes: { timeRestore } }) => getDashboardUrl(id, timeRestore),
[getDashboardUrl]
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export class FormatEditorSamples extends PureComponent<FormatEditorSamplesProps>
defaultMessage: 'Input',
}),
render: (input: {} | string) => {
return typeof input === 'object' ? JSON.stringify(input) : input;
return (typeof input === 'object' ? JSON.stringify(input) : input) as string;
},
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export const getLogLevelBadgeCell =
return (
<LogLevelBadge
logLevel={value}
fallback={<span data-test-subj={`${dataTestSubj}-unknown`}>{value}</span>}
fallback={<span data-test-subj={`${dataTestSubj}-unknown`}>{value as string}</span>}
data-test-subj={dataTestSubj}
css={badgeCss}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* License v3.0 only", or the "Server Side Public License, v 1".
*/

import React, { useCallback } from 'react';
import React, { ChangeEvent, useCallback } from 'react';
import { EuiFormRow, EuiRange, EuiRangeProps } from '@elastic/eui';

import { FieldHook, getFieldValidityAndErrorMessage } from '../../hook_form_lib';
Expand All @@ -23,10 +23,13 @@ export const RangeField = ({ field, euiFieldProps = {}, idAria, ...rest }: Props
const { isInvalid, errorMessage } = getFieldValidityAndErrorMessage(field);
const { onChange: onFieldChange } = field;

const onChange: EuiRangeProps['onChange'] = useCallback(
const onChange = useCallback<NonNullable<EuiRangeProps['onChange']>>(
(e) => {
const event = { ...e, value: `${e.currentTarget.value}` };
onFieldChange(event);
const event = {
...e,
value: `${e.currentTarget.value}`,
};
onFieldChange(event as ChangeEvent<{ name?: string; value: string; checked?: boolean }>);
},
[onFieldChange]
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ describe('Guided setup', () => {
expect(
find('guidePanelStepDescription')
.first()
.containsMatchingElement(<p>{testGuideConfig.steps[2].description}</p>)
.containsMatchingElement(<p>{testGuideConfig.steps[2].description as string}</p>)
).toBe(true);
});

Expand All @@ -475,7 +475,7 @@ describe('Guided setup', () => {
.containsMatchingElement(
<ul>
{testGuideConfig.steps[0].descriptionList?.map((description, i) => (
<li key={i}>{description}</li>
<li key={i}>{description as string}</li>
))}
</ul>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ export const HoverActionPopover = ({
panelStyle={{ minWidth: '24px' }}
display={display}
>
{title && (
{(title as string) && (
<EuiPopoverTitle className="eui-textBreakWord" css={{ maxWidth: '200px' }}>
{title}
{title as string}
</EuiPopoverTitle>
)}
<EuiFlexGroup wrap gutterSize="none" alignItems="center" justifyContent="spaceBetween">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export const BreakdownFieldSelector = ({
return options;
}, [dataView, breakdown.field]);

const onChange: ToolbarSelectorProps['onChange'] = useCallback(
const onChange = useCallback<NonNullable<ToolbarSelectorProps['onChange']>>(
(chosenOption) => {
const field = chosenOption?.value
? dataView.fields.find((currentField) => currentField.name === chosenOption.value)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const TimeIntervalSelector: React.FC<TimeIntervalSelectorProps> = ({
chart,
onTimeIntervalChange,
}) => {
const onChange: ToolbarSelectorProps['onChange'] = useCallback(
const onChange = useCallback<NonNullable<ToolbarSelectorProps['onChange']>>(
(chosenOption) => {
const selectedOption = chosenOption?.value;
if (selectedOption) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ function MaxBarsParamEditor({
setValidity(isValid);
}, [isValid, setValidity]);

const onChange: EuiFieldNumberProps['onChange'] = useCallback(
const onChange = useCallback<NonNullable<EuiFieldNumberProps['onChange']>>(
(ev) => setValue(ev.target.value === '' ? '' : parseFloat(ev.target.value)),
[setValue]
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ function NumberIntervalParamEditor({
setTouched,
setValidity,
setValue,
}: AggParamEditorProps<string | undefined>) {
}: AggParamEditorProps<string | undefined | number>) {
const field = agg.getField();
const fieldSupportsAuto = !field || field.type === 'number';
const isAutoChecked = fieldSupportsAuto && isAutoInterval(value);
Expand All @@ -85,12 +85,12 @@ function NumberIntervalParamEditor({
setValidity(isValid);
}, [isValid, setValidity]);

const onChange: EuiFieldNumberProps['onChange'] = useCallback(
const onChange = useCallback<NonNullable<EuiFieldNumberProps['onChange']>>(
({ target }) => setValue(isNaN(target.valueAsNumber) ? '' : target.valueAsNumber),
[setValue]
);

const onAutoSwitchChange: EuiSwitchProps['onChange'] = useCallback(
const onAutoSwitchChange = useCallback<EuiSwitchProps['onChange']>(
(e) => {
const isAutoSwitchChecked = e.target.checked;

Expand All @@ -105,7 +105,7 @@ function NumberIntervalParamEditor({
label={label}
fullWidth={true}
isInvalid={showValidation && !isValid}
helpText={get(editorConfig, 'interval.help')}
helpText={get(editorConfig, 'interval.help') as string}
>
<EuiFlexGroup gutterSize="s" responsive={false} direction={'column'}>
<EuiFlexItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ function RadiusRatioOptionControl({ editorStateParams, setStateParamValue }: Agg
}
});

const onChange: EuiRangeProps['onChange'] = useCallback(
const onChange = useCallback<NonNullable<EuiRangeProps['onChange']>>(
(e) => setStateParamValue(PARAM_NAME, parseFloat(e.currentTarget.value)),
[setStateParamValue]
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export const TableVisBasic = memo(
defaultMessage: 'Data table visualization',
});

const onColumnResize: EuiDataGridProps['onColumnResize'] = useCallback(
const onColumnResize = useCallback<NonNullable<EuiDataGridProps['onColumnResize']>>(
({ columnId, width }) => {
const colIndex = columns.findIndex((c) => c.id === columnId);
setColumnsWidth({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ export function FieldSelect({
);

const onFieldSelectItemChange = useCallback(
(index: number = 0, [selectedItem]) => {
(index: number = 0, [selectedItem]: Array<EuiComboBoxOptionOption<string>>) => {
onChange(updateItem(selectedIds, selectedItem?.value, index));
},
[selectedIds, onChange]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,11 @@ export const ComboBoxSelect = ({
const [availableIndexes, setAvailableIndexes] = useState<IdsWithTitle>([]);
const [selectedOptions, setSelectedOptions] = useState<SelectedOptions>([]);

const onComboBoxChange: EuiComboBoxProps<IndexPatternValue>['onChange'] = useCallback(
const onComboBoxChange = useCallback<
NonNullable<EuiComboBoxProps<IndexPatternValue>['onChange']>
>(
([selected]) => {
onIndexChange(selected ? { id: selected.id } : '');
onIndexChange(selected ? { id: selected.id! } : '');
},
[onIndexChange]
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const FieldTextSelect = ({
const [inputValue, setInputValue] = useState<string>();
const { indexPatternString } = fetchedIndex;

const onFieldTextChange: EuiFieldTextProps['onChange'] = useCallback((e) => {
const onFieldTextChange = useCallback<NonNullable<EuiFieldTextProps['onChange']>>((e) => {
setInputValue(e.target.value);
}, []);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,16 @@ export const ViewPeopleInSpaceAlertPage = withRouter(({ http, id }: Props) => {
{isEmpty(alertState.alerts) ? (
<EuiCallOut title="No Alerts!" color="warning" iconType="help">
<p>
The people in {alert.params.craft} at the moment <b>are not</b> {alert.params.op}{' '}
{alert.params.outerSpaceCapacity}
The people in {alert.params.craft as string} at the moment <b>are not</b>{' '}
{alert.params.op as string} {alert.params.outerSpaceCapacity as string}
</p>
</EuiCallOut>
) : (
<Fragment>
<EuiCallOut title="Active State" color="success" iconType="user">
<p>
The rule has been triggered because the people in {alert.params.craft} at the moment{' '}
{alert.params.op} {alert.params.outerSpaceCapacity}
The rule has been triggered because the people in {alert.params.craft as string} at
the moment {alert.params.op as string} {alert.params.outerSpaceCapacity as string}
</p>
</EuiCallOut>
<EuiSpacer size="l" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ export const SearchBarWrapper: FC<SearchBarProps> = ({

const [error, setError] = useState<string | undefined>();

const onQuerySubmit: SearchBarOwnProps['onQuerySubmit'] = useCallback(
const onQuerySubmit = useCallback<NonNullable<SearchBarOwnProps['onQuerySubmit']>>(
(payload, isUpdate) => {
if (payload.query.language === SEARCH_QUERY_LANGUAGE.KUERY) {
if (payload.query?.language === SEARCH_QUERY_LANGUAGE.KUERY) {
try {
// Validates the query
fromKueryExpression(payload.query.query);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const PageHeader: FC = () => {
autoRefreshSelector: true,
});

const updateTimeState: FullTimeRangeSelectorProps['callback'] = useCallback(
const updateTimeState = useCallback<NonNullable<FullTimeRangeSelectorProps['callback']>>(
(update) => {
setGlobalState({
time: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,14 @@ export interface MarkdownEditorRef {
const MarkdownEditorComponent = forwardRef<MarkdownEditorRef, MarkdownEditorProps>(
({ ariaLabel, dataTestSubj, editorId, height, onChange, value, disabledUiPlugins }, ref) => {
const astRef = useRef<EuiMarkdownAstNode | undefined>(undefined);
const [markdownErrorMessages, setMarkdownErrorMessages] = useState([]);
const onParse: EuiMarkdownEditorProps['onParse'] = useCallback((err, { messages, ast }) => {
setMarkdownErrorMessages(err ? [err] : messages);
astRef.current = ast;
}, []);
const [markdownErrorMessages, setMarkdownErrorMessages] = useState<Array<string | Error>>([]);
const onParse = useCallback<NonNullable<EuiMarkdownEditorProps['onParse']>>(
(err, { messages, ast }) => {
setMarkdownErrorMessages(err ? [err] : messages);
astRef.current = ast;
},
[]
);

const { parsingPlugins, processingPlugins, uiPlugins } = usePlugins(disabledUiPlugins);
const editorRef = useRef<EuiMarkdownEditorRef>(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ export const CasesParamsFieldsComponent: React.FunctionComponent<
<EuiFormRow
fullWidth
id="timeWindow"
error={errors.timeWindow}
error={errors.timeWindow as string[]}
isInvalid={
errors.timeWindow !== undefined &&
Number(errors.timeWindow.length) > 0 &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ export const sortOptions: EuiSelectOption[] = [

export const SortActivity = React.memo<FilterActivityProps>(
({ sortOrder, onOrderChange, isLoading = false }) => {
const onChange: EuiSelectProps['onChange'] = useCallback(
const onChange = useCallback<NonNullable<EuiSelectProps['onChange']>>(
(e) => {
onOrderChange(e.target.value);
onOrderChange(e.target.value as UserActivitySortOrder);
},
[onOrderChange]
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export const groupPanelRenderer: GroupPanelRenderer<FindingsGroupingAggregation>
css={css`
word-break: break-all;
`}
title={bucket.resourceName?.buckets?.[0]?.key}
title={bucket.resourceName?.buckets?.[0]?.key as string}
>
<strong>{bucket.key_as_string}</strong> {bucket.resourceName?.buckets?.[0]?.key}
</EuiTextBlockTruncate>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export const groupPanelRenderer: GroupPanelRenderer<VulnerabilitiesGroupingAggre
css={css`
word-break: break-all;
`}
title={bucket.resourceId?.buckets?.[0]?.key}
title={bucket.resourceId?.buckets?.[0]?.key as string}
>
<strong>{bucket.key_as_string}</strong> {bucket.resourceId?.buckets?.[0]?.key}
</EuiTextBlockTruncate>
Expand Down
Loading

0 comments on commit c30aeea

Please sign in to comment.