Material-ui: [Autocomplete] @material-ui/lab v4.0.0-alpha.54 breaks existing code

Created on 24 May 2020  路  6Comments  路  Source: mui-org/material-ui

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.

  • [x] The issue is present in the latest release.
  • [x] I have searched the issues of this repository and believe that this is not a duplicate.

Current Behavior 馃槸

TypeScript errors when compiling the component which wraps Autocomplete.

Expected Behavior 馃

No TypeScript errors.

Steps to Reproduce 馃暪

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:

  1. In /package.json, change @material-ui/lab version to 4.0.0-alpha.54 and run yarn.
  2. cd packages/formik-mui
  3. yarn build
  4. You will see the following four errors:
src/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'> {
                    ~~~~~~~~~~~~~~~~~~~~~~

Your Environment 馃寧

| Tech | Version |
| ----------- | ------- |
| Material-UI | v4.?.? |
| React | 16.13.1 |
| Browser | N/A |
| TypeScript | 3.9.3 |
| etc. | |

Autocomplete question typescript waiting for 馃憤

Most helpful comment

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>

All 6 comments

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.

Was this page helpful?
0 / 5 - 0 ratings