Jessica
Jessica

Reputation: 9830

MUI Props giving error: `requires between 4 and 5 type arguments`

I am trying to wrap a MuiAutocomplete around my own custom component and also pass in AutocompleteProps as a prop, while using typescript. Here's what I have:

type Props = {
  autoCompleteProps?: AutocompleteProps<T>
  label: string
  loading?: boolean
}

const AutoComplete: React.FC<Props> = ({
  autoCompleteProps,
  label,
  loading,
}) => {
  return (
    <MuiAutocomplete {...autoCompleteProps}/>
  )
}

But I get the following error on: autoCompleteProps?: AutocompleteProps<T>

Generic type 'AutocompleteProps<T, Multiple, DisableClearable, FreeSolo, ChipComponent>' requires between 4 and 5 type arguments

What am I doing wrong and how can I fix it?

And I also want to make renderInput optional

Upvotes: 6

Views: 7900

Answers (3)

fer0n
fer0n

Reputation: 1134

import { Autocomplete, AutocompleteProps, TextField } from '@mui/material';
import React, { ReactNode } from 'react';

export interface WrappedAutoCompleteProps<
    T,
    Multiple extends boolean | undefined,
    DisableClearable extends boolean | undefined,
    FreeSolo extends boolean | undefined = undefined,
> extends Omit<AutocompleteProps<T | string, Multiple, DisableClearable, FreeSolo>, 'renderInput'> {
    renderInput?: AutocompleteProps<T | string, Multiple, DisableClearable, FreeSolo>['renderInput'];
    label?: ReactNode;
}

export default function WrappedAutoComplete<
    T,
    Multiple extends boolean | undefined = undefined,
    DisableClearable extends boolean | undefined = undefined,
    FreeSolo extends boolean | undefined = undefined,
>({ label, ...props }: WrappedAutoCompleteProps<T, Multiple, DisableClearable, FreeSolo>) {
    return <Autocomplete renderInput={(params) => <TextField {...params} label={label} />} {...props} />;
}

Usage:

<WrappedAutoComplete
    label="label here"
    multiple
    freeSolo
    options={[]}
/>

Upvotes: 1

Okan Karadag
Okan Karadag

Reputation: 3045

AutocompleteProps has five generic value and one has default value, others required.

export interface CustomAutoCompleteProps<T> {
    autocompleteProps: AutocompleteProps<T, boolean | undefined, boolean | undefined, boolean | undefined>;
    label: string;
    loading?: boolean;
}

Component:

export const CustomAutoComplete = <T,>(props: CustomAutoCompleteProps<T>) => {
  const { label, autocompleteProps, loading } = props;

  return <Autocomplete {...autocompleteProps} />;
};

And I also want to make renderInput optional

that's not possible, renderInput and options are required field.

interface IOptions {
  label: string;
  year: number;
}

export const AutoCompleteTest = () => {
  let options: CustomAutoCompleteProps<IOptions> = {
    label: "test",
    loading: false,
    autocompleteProps: {
      options: [
        { label: "test", year: 2021 },
        { label: "asd", year: 2222 },
      ],
      renderInput: (params) => <TextField {...params} label={"label"} />,
    },
  };
  return <CustomAutoComplete {...options} />;
};

Edit interesting-bash-yicwbc

Upvotes: 4

johannchopin
johannchopin

Reputation: 14843

As TypeScript says, AutocompleteProps needs to have 4 to 5 type arguments as it's defined like the following:

export interface AutocompleteProps<
  T,
  Multiple extends boolean | undefined,
  DisableClearable extends boolean | undefined,
  FreeSolo extends boolean | undefined,
  ChipComponent extends React.ElementType = ChipTypeMap['defaultComponent'],
> {
  // ..
}

ChipComponent has a default value that's why this props require 5 or 4 arguments.

For the others you will need to specify which type to use.

So what you can do is add some generics value to Props and simply pass them to the AutocompleteProps one:

type Props<
  T,
  Multiple extends boolean | undefined = undefined,
  DisableClearable extends boolean | undefined = undefined,
  FreeSolo extends boolean | undefined = undefined
> = {
  autoCompleteProps?: AutocompleteProps<
    T,
    Multiple,
    DisableClearable,
    FreeSolo
  >;
  label: string;
  loading?: boolean;
};

If you don't care about them in your custom API you can use simple default values:

type Props<T> = {
  autoCompleteProps?: AutocompleteProps<T, undefined, undefined, undefined>;
  label: string;
  loading?: boolean;
};

Upvotes: 1

Related Questions