Wt.N
Wt.N

Reputation: 1658

Type 'string' is not assignable to type '"menu" | "selectedMenu" | undefined'

I'm making multiple select in typescript, material-ui, React. I need to set MenuProps.variant = 'menu', but I'm facing the error,

Type '{ variant: string; PaperProps: { style: { maxHeight: number; width: number; }; }; }' is not assignable to type 'Partial'. Types of property 'variant' are incompatible. Type 'string' is not assignable to type '"menu" | "selectedMenu" | undefined'.

for the below code. How to resolve this error?

import React from 'react';
import Input from '@material-ui/core/Input';
import MenuItem from '@material-ui/core/MenuItem';
import Select from '@material-ui/core/Select';

const ITEM_HEIGHT = 48;
const ITEM_PADDING_TOP = 8;
const MenuProps = {
  variant: 'menu',
  PaperProps: {
    style: {
      maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
      width: 250,
    },
  },
};

const names = [
  'Oliver Hansen',
  'Van Henry',
  'April Tucker',
  'Ralph Hubbard',
  'Omar Alexander',
  'Carlos Abbott',
  'Miriam Wagner',
  'Bradley Wilkerson',
  'Virginia Andrews',
  'Kelly Snyder',
];


export default function MultipleSelect() {
  const classes = useStyles();
  const theme = useTheme();
  const [personName, setPersonName] = React.useState<string[]>([]);

  const handleChange = (event: React.ChangeEvent<{ value: unknown }>) => {
    setPersonName(event.target.value as string[]);
  };

  return (
        <Select
          multiple
          value={personName}
          onChange={handleChange}
          input={<Input />}
          MenuProps={MenuProps}
        >
          {names.map((name) => (
            <MenuItem key={name} value={name} style={getStyles(name, personName, theme)}>
              {name}
            </MenuItem>
          ))}
        </Select>
      )
}

Reference
https://material-ui.com/api/menu/
https://material-ui.com/components/selects/#multiple-select

Upvotes: 2

Views: 5177

Answers (2)

Ryan Cogswell
Ryan Cogswell

Reputation: 81006

You can import the MenuProps type from Material-UI with:

import { MenuProps as MenuPropsType } from "@material-ui/core/Menu";

Then you can use this like the following:

const MenuProps: Partial<MenuPropsType> = {
  variant: "menu",
  PaperProps: {
    style: {
      maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
      width: 250
    }
  }
};

You use Partial<MenuPropsType> (as it also is in the Select type definition) because Select automatically adds the required open prop (if you remove Partial, it will complain about the open prop not being specified).

Here's a working example based on your code:

import React from "react";
import { MenuProps as MenuPropsType } from "@material-ui/core/Menu";
import Input from "@material-ui/core/Input";
import MenuItem from "@material-ui/core/MenuItem";
import Select from "@material-ui/core/Select";

const ITEM_HEIGHT = 48;
const ITEM_PADDING_TOP = 8;
const MenuProps: Partial<MenuPropsType> = {
  variant: "menu",
  PaperProps: {
    style: {
      maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
      width: 250
    }
  }
};

const names = [
  "Oliver Hansen",
  "Van Henry",
  "April Tucker",
  "Ralph Hubbard",
  "Omar Alexander",
  "Carlos Abbott",
  "Miriam Wagner",
  "Bradley Wilkerson",
  "Virginia Andrews",
  "Kelly Snyder"
];

export default function MultipleSelect() {
  const [personName, setPersonName] = React.useState<string[]>([]);

  const handleChange = (event: React.ChangeEvent<{ value: unknown }>) => {
    setPersonName(event.target.value as string[]);
  };

  return (
    <Select
      multiple
      value={personName}
      onChange={handleChange}
      input={<Input />}
      MenuProps={MenuProps}
    >
      {names.map((name) => (
        <MenuItem key={name} value={name}>
          {name}
        </MenuItem>
      ))}
    </Select>
  );
}

Edit MenuProps type

Upvotes: 2

Viet
Viet

Reputation: 12787

Because variant only receive type is "menu" | "selectedMenu" | undefined. But you pass a value is "menu" without type. So it will auto has type is string. You need to define a type for variant. Like this:

const MenuProps = {
  variant: 'menu' as 'menu',
  ...
};

Upvotes: 3

Related Questions