The type definition for AutocompleteProps has changed which breaks existing code. While the new type definition looks more robust, I can't figure out how to make it work for my use case. All I am trying to do is to wrap the Autocomplete component and set some of its properties to make it work the way I want. However any other properties sent by the parent component should be passed through.
TypeScript errors when compiling the component which wraps Autocomplete.
No TypeScript errors.
Note: For now I am pointing to my repo. I will try to create a Code Sandbox tomorrow.
Please see my component here. Code reproduced below:
export interface MultiSelectFieldProps<OptionType>
extends Omit<AutocompleteProps<any>, 'renderInput'> {
name: string;
label?: string;
}
export function MultiSelectField<OptionType>({
name,
label,
...rest
}: MultiSelectFieldProps<OptionType>) {
const [field, meta] = useField(name);
const formik = useFormikContext<any>();
const handleChange = (event: any, value: any) => {
formik.setFieldValue(name, value);
};
return (
<Autocomplete
multiple
disableClearable
disableCloseOnSelect
value={field.value}
renderInput={({ helperText, ...params }: TextFieldProps) => (
<TextField
label={label}
helperText={
meta.touched && meta.error ? meta.error : helperText
}
error={!!(meta.touched && meta.error)}
margin="normal"
{...params}
/>
)}
autoComplete={true}
autoHighlight={true}
clearOnEscape={true}
onChange={handleChange}
{...rest}
/>
);
}
Steps:
cd packages/formik-muiyarn buildsrc/MultiSelectField/MultiSelectField.tsx:7:18 - error TS2314: Generic type 'AutocompleteProps<T, Multiple, DisableClearable, FreeSolo>' requires 4 type argument(s).
7 extends Omit<AutocompleteProps<any>, 'renderInput'> {
~~~~~~~~~~~~~~~~~~~~~~
src/MultiSelectField/MultiSelectField.tsx:26:13 - error TS2322: Type 'true' is not assignable to type 'undefined'.
26 multiple
~~~~~~~~
../../node_modules/@material-ui/lab/useAutocomplete/useAutocomplete.d.ts:222:3
222 multiple?: Multiple;
~~~~~~~~
The expected type comes from property 'multiple' which is declared here on type 'IntrinsicAttributes & AutocompleteProps<unknown, undefined, undefined, undefined>'
src/MultiSelectField/MultiSelectField.tsx:27:13 - error TS2322: Type 'true' is not assignable to type 'undefined'.
27 disableClearable
~~~~~~~~~~~~~~~~
../../node_modules/@material-ui/lab/useAutocomplete/useAutocomplete.d.ts:84:3
84 disableClearable?: DisableClearable;
~~~~~~~~~~~~~~~~
The expected type comes from property 'disableClearable' which is declared here on type 'IntrinsicAttributes & AutocompleteProps<unknown, undefined, undefined, undefined>'
src/TimezoneField/TimezoneField.tsx:37:18 - error TS2314: Generic type 'AutocompleteProps<T, Multiple, DisableClearable, FreeSolo>' requires 4 type argument(s).
37 extends Omit<AutocompleteProps<any>, 'options' | 'renderInput'> {
~~~~~~~~~~~~~~~~~~~~~~
| Tech | Version |
| ----------- | ------- |
| Material-UI | v4.?.? |
| React | 16.13.1 |
| Browser | N/A |
| TypeScript | 3.9.3 |
| etc. | |
The generic parameters of AutocompleteProps changed.
Oops, I have forgotten to mention this breaking change in the changelog: #20949.
Thanks @eps1lon and @oliviertassinari. I will try to solve this myself and/or use the support route.
A quick observation is that the type definitions are getting quite complex now and it would be good to have one example of extending/wrapping a Material-UI component in the TypeScript section of the docs. The use case is that we would like to wrap a Material-UI component with our own, adding a few properties to be used inside the wrapper and removing some properties because they will be supplied by the wrapper.
You should find an example in the TypeScript tests. I think that we can wait for more interested from the community before making an example.
I believe all you'd have to change now is, for instance, from:
return (
<Autocomplete<string>
multiple
disableClearable
options={[]}
freeSolo
...
/>
)
to <Autocomplete<string, true, true, true>
Thanks @picosam - that's an interesting solution.
I personally solved this by using the render prop pattern (see here). It is a good generic solution to wrap/extend Material-UI components. I will be using it more often now.
Most helpful comment
I believe all you'd have to change now is, for instance, from:
to
<Autocomplete<string, true, true, true>