Skip to content

[material-ui][Autocomplete] Type issue once wrapped with styled() #21727

Closed

Description

@hiahmedhameed

I'm trying to use Autocomplete with styled-components in typescript environment. But when using the component, linter start to complain about styled autocomplete component. I checked for this issue but not sure if it is duplicate. Could not find something related?

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

Current Behavior 😯

No overload matches this call.
  Overload 2 of 2, '(props: StyledComponentPropsWithAs<(<T, Multiple extends boolean | undefined = undefined, DisableClearable extends boolean | undefined = undefined, FreeSolo extends boolean | undefined = undefined>(props: AutocompleteProps<T, Multiple, DisableClearable, FreeSolo>) => Element), DefaultTheme, {}, never>): ReactElement<...>', gave the following error.
    Type '(_event: React.ChangeEvent<{}>, value: OptionData | null) => void | undefined' is not assignable to type '(event: ChangeEvent<{}>, value: unknown, reason: AutocompleteChangeReason, details?: AutocompleteChangeDetails<unknown> | undefined) => void'.
  Overload 2 of 2, '(props: StyledComponentPropsWithAs<(<T, Multiple extends boolean | undefined = undefined, DisableClearable extends boolean | undefined = undefined, FreeSolo extends boolean | undefined = undefined>(props: AutocompleteProps<T, Multiple, DisableClearable, FreeSolo>) => Element), DefaultTheme, {}, never>): ReactElement<...>', gave the following error.
    Type '(data: OptionData) => string' is not assignable to type '(option: unknown) => string'.
  Overload 2 of 2, '(props: StyledComponentPropsWithAs<(<T, Multiple extends boolean | undefined = undefined, DisableClearable extends boolean | undefined = undefined, FreeSolo extends boolean | undefined = undefined>(props: AutocompleteProps<T, Multiple, DisableClearable, FreeSolo>) => Element), DefaultTheme, {}, never>): ReactElement<...>', gave the following error.
    Type '(option: OptionData) => boolean' is not assignable to type '(option: unknown, value: unknown) => boolean'.  TS2769
     62 |   return (
     63 |     <StyledFormControl>
  > 64 |       <StyledAutocomplete
       |       ^
    65 |         id={id}
    66 |         options={options}
    67 |         // classes={classes}

I started to add one prop by another then i realised the following:

<StyledAutocomplete
        id={id}
        options={options}                                                                          // type of OptionData[]
        onChange={(_event: React.ChangeEvent<{}>, value) =>        // <<== if i set value: OptionData | null linter will complain
          onChange && onChange(value as OptionData | null)
        }
        value={currentValue}
        getOptionLabel={data => (data as OptionData).label}             // <<== if i set data: OptionData | null linter will complain
        getOptionSelected={option =>                                                // <<== if i set option: OptionData | null linter will complain
          (option as OptionData).label === currentValue?.label
        }
        autoHighlight
        renderInput={params => (
          <TextField
            {...params}
            error={!!error}
            name={name}
            label={label}
            variant="standard"
          />
        )}
      />

Expected Behavior 🤔

Would it be possible to take T type of the options property and pass it throw all function that working with the same type ?

Steps to Reproduce 🕹

Simply styled Autocomplete with styled-components.

[...]

const StyledAutocomplete = styled(Autocomplete)`
  & .MuiInputBase-root {
    height: 4.1rem;
  }
  & label: {
    fontsize: 2rem;
  }
`;

[....]


<StyledAutocomplete
        id={id}
        options={options}
        // onChange={(_event: React.ChangeEvent<{}>, value: OptionData | null) =>                 // <<== Linter error
        //   onChange && onChange(value)
        // }
        value={currentValue}
        // getOptionLabel={(data: OptionData) => data.label}         // <<== Linter error
        // getOptionSelected={(option: OptionData) =>.                  // <<== Linter error
        //   option.label === currentValue?.label
        // }
        autoHighlight
        renderInput={params => (
          <TextField
            {...params}
            error={!!error}
            name={name}
            label={label}
            variant="standard"
          />
        )}
      />

Context 🔦

As consistency we use styled-components as a generic way of styling. We need to use the same here. The styling suggestion works fine using makeStyles

Your Environment 🌎

Tech Version
Material-UI v4.9.12
React 16.13.1
Browser Chrome 83.0.4103.116
TypeScript 3.8.0
OS MacOS.

Activity

  1. oliviertassinari commented on Jul 9, 2020

    @oliviertassinari
    Member

    This makes me think of #19842. Do you have a reproduction?

  2. oliviertassinari commented on Jul 10, 2020

    @oliviertassinari
  3. hiahmedhameed commented on Jul 13, 2020

    @hiahmedhameed
    Author

    Hi @oliviertassinari
    Sorry for taking long preparing sandbox sample.

    TBH not sure how the types working in sandbox ? But I still believe we have kind of the same issue.

    Please checkout this link:
    https://codesandbox.io/s/strange-borg-wetsr

    The any type in arguments at least should be {} from options type. If you may note that i used cascading type like (data as AutocompleteOptionData).label which i think make no sense with typescript. Just because the argument taking type of unknown.

    Hope that can help.

  4. oliviertassinari commented on Jul 13, 2020

    @oliviertassinari
    Member
  5. hiahmedhameed commented on Jul 13, 2020

    @hiahmedhameed
    Author

    That's actually a solution but dose that considered as permanent solution ?

    Also why styled-components dose not extend the props internally ? This is odd when I have to do the extending myself right ?

    What do you think ?

  6. oliviertassinari commented on Jul 13, 2020

    @oliviertassinari
    Member

    I'm not aware of a better solution, but I'm no expert on TypeScript either. The concern seems something we would at the very least to document.

  7. 11 remaining items

  8. enheit commented on Jul 14, 2021

    @enheit

    I'm not sure if this topic is related to my issue but it looks very similar.

    I use styled from @material-ui/core to wrap Autocomplete. After using it inside my component all options are set to unknown. See picture

    image

    Styles look like this

    import { styled, Autocomplete as AutocompleteOriginal } from '@material-ui/core'
    
    export const Autocomplete = styled(AutocompleteOriginal)(props => ({
      // styles go here
    }))

    If I use Autocomplete component directly from the @material-ui/core the options types are correct.

    P.S. I use @material-ui/core: 5.0.0-beta.0

  9. changed the title [-]Style Autocomplete component with `styled-components`[/-] [+][Autocomplete] Type issue once wrapped with styled()[/+] on Jul 14, 2021
  10. oliviertassinari commented on Jul 14, 2021

    @oliviertassinari
    Member

    @enheit Yes, it's the same issue. I have updated #21727 (comment) to better function.

  11. added
    ready to takeHelp wanted. Guidance available. There is a high chance the change will be accepted
    and removed
    ready to takeHelp wanted. Guidance available. There is a high chance the change will be accepted
    on Jul 14, 2021
  12. ortonomy commented on Mar 16, 2022

    @ortonomy

    The approach in https://codesandbox.io/s/pedantic-tharp-bdwj8?file=/src/Autocomplete.tsx seems to work, I think that we can go with the docs.

    @oliviertassinari -- there are two approaches here and comments indicate the second doesn't work -- which approach exactly where you proposing?

    1 or 2?

  13. NunchakusLei commented on Apr 6, 2023

    @NunchakusLei

    I found the following code make it works for me. Not sure if it will help or not since I'm using MUI v5 and not the version you mentioned. Post it here in case it helps,

    const StyledAutocomplete = styled(Autocomplete)`
      & .MuiInputBase-root {
        height: 4.1rem;
      }
      & label: {
        fontsize: 2rem;
      }
    ` as typeof Autocomplete;
  14. mapache-salvaje commented on Nov 28, 2023

    @mapache-salvaje
    Contributor

    Revisiting this in Q4 '23, it looks like we could close this issue by documenting @NunchakusLei's solution in the Autocomplete doc.

  15. changed the title [-][Autocomplete] Type issue once wrapped with styled()[/-] [+][material-ui][Autocomplete] Type issue once wrapped with styled()[/+] on Nov 28, 2023
  16. added
    scope: autocompleteChanges related to the autocomplete. This includes ComboBox.
    and removed
    scope: autocompleteChanges related to the autocomplete. This includes ComboBox.
    on Aug 17, 2025
  17. github-actions commented on Oct 22, 2026

    @github-actions
    Contributor

    This issue has been closed. If you have a similar problem but not exactly the same, please open a new issue.
    Now, if you have additional information related to this issue or things that could help future readers, feel free to leave a comment.


    @hiahmedhameed Thanks again for creating this issue! If you have a moment, we would love to hear your thoughts on how we handled it with this short feedback form.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    docsImprovements or additions to the documentation.ready to takeHelp wanted. Guidance available. There is a high chance the change will be acceptedscope: autocompleteChanges related to the autocomplete. This includes ComboBox.typescript

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions