mui / material-ui

Material UI: Comprehensive React component library that implements Google's Material Design. Free forever.
https://mui.com/material-ui/
MIT License
93.65k stars 32.22k forks source link

[MUI v6] Box component warns about TypeScript type #43955

Open mtr1990 opened 2 weeks ago

mtr1990 commented 2 weeks ago

Steps to reproduce

Based on the example provided from MUI https://github.com/mui/material-ui/tree/master/examples/material-ui-nextjs-ts

I have added the following code

import * as React from 'react';
import Container from '@mui/material/Container';
import Box, { BoxProps } from '@mui/material/Box';

function Li({ children, ...other }: BoxProps) {
  return (
    <Box
      component={'li'}
      {...other}
    >
      {children}
    </Box>
  );
}

function Ul({ children, ...other }: BoxProps) {
  return (
    <Box
      component={'ul'}
      {...other}
    >
      {children}
    </Box>
  );
}

function Svg({ children, ...other }: BoxProps) {
  return (
    <Box
      component={'svg'}
      width='24'
      height='25'
      viewBox='0 0 24 25'
      fill='none'
      xmlns='http://www.w3.org/2000/svg'
      {...other}
    >
      <path
        d='M4 22.5098L7.9997 15.5098H23.9998L19.9997 22.5098H4Z'
        fill='#3777E3'
      />
      <path
        d='M16.0003 15.5098H24.0001L16.0003 1.50977H8L16.0003 15.5098Z'
        fill='#FFCF63'
      />
      <path
        d='M0 15.5098L4.00024 22.5098L12 8.50977L7.99994 1.50977L0 15.5098Z'
        fill='#11A861'
      />
    </Box>
  );
}

export default function Home() {
  return (
    <Container maxWidth='lg'>
      <Svg />

      <Ul>
        <Li>Item 1</Li>
        <Li>Item 2</Li>
        <Li>Item 3</Li>
        <Li>Item 4</Li>
      </Ul>
    </Container>
  );
}

I use this method in MUI v5 without any problems. However, the error appears in MUI v6. I read in the documentation that components were removed in MUI v6 https://github.com/mui/material-ui/releases/tag/v6.0.0-rc.0

But I still see the document is still in use: https://mui.com/material-ui/react-box/#basics

So the component in Box is actually removed?

Current behavior

Error message appears

No overload matches this call.
  Overload 1 of 2, '(props: { component: "li"; } & BoxOwnProps<Theme> & Omit<Omit<DetailedHTMLProps<LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>, "ref"> & { ...; }, keyof BoxOwnProps<...>>): Element | null', gave the following error.
    Type '{ children: ReactNode; ref?: Ref<unknown> | undefined; sx?: SxProps<Theme> | undefined; border?: ResponsiveStyleValue<number | (string & {}) | "inset" | "hidden" | "-moz-initial" | ... 194 more ... | undefined> | ((theme: Theme) => ResponsiveStyleValue<...>); ... 378 more ...; component: "li"; }' is not assignable to type 'Omit<Omit<DetailedHTMLProps<LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>, "ref"> & { ref?: ((instance: HTMLLIElement | null) => void | (() => VoidOrUndefinedOnly)) | ... 2 more ... | undefined; }, keyof BoxOwnProps<...>>'.
      Types of property 'onToggle' are incompatible.
        Type 'ToggleEventHandler<HTMLDivElement> | undefined' is not assignable to type 'ToggleEventHandler<HTMLLIElement> | undefined'.
          Type 'ToggleEventHandler<HTMLDivElement>' is not assignable to type 'ToggleEventHandler<HTMLLIElement>'.
            Type 'HTMLDivElement' is missing the following properties from type 'HTMLLIElement': type, value
  Overload 2 of 2, '(props: DefaultComponentProps<BoxTypeMap<{}, "div", Theme>>): Element | null', gave the following error.
    Type '{ children: ReactNode; ref?: Ref<unknown> | undefined; sx?: SxProps<Theme> | undefined; border?: ResponsiveStyleValue<number | (string & {}) | "inset" | "hidden" | "-moz-initial" | ... 194 more ... | undefined> | ((theme: Theme) => ResponsiveStyleValue<...>); ... 378 more ...; component: string; }' is not assignable to type 'IntrinsicAttributes & BoxOwnProps<Theme> & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & { ...; }, keyof BoxOwnProps<...>>'.
      Property 'component' does not exist on type 'IntrinsicAttributes & BoxOwnProps<Theme> & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & { ...; }, keyof BoxOwnProps<...>>'.
No overload matches this call.
  Overload 1 of 2, '(props: { component: "ul"; } & BoxOwnProps<Theme> & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLUListElement>, HTMLUListElement>, "ref"> & { ...; }, keyof BoxOwnProps<...>>): Element | null', gave the following error.
    Type '{ children: ReactNode; ref?: Ref<unknown> | undefined; sx?: SxProps<Theme> | undefined; border?: ResponsiveStyleValue<number | (string & {}) | "inset" | "hidden" | "-moz-initial" | ... 194 more ... | undefined> | ((theme: Theme) => ResponsiveStyleValue<...>); ... 378 more ...; component: "ul"; }' is not assignable to type 'Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLUListElement>, HTMLUListElement>, "ref"> & { ...; }, keyof BoxOwnProps<...>>'.
      Types of property 'onToggle' are incompatible.
        Type 'ToggleEventHandler<HTMLDivElement> | undefined' is not assignable to type 'ToggleEventHandler<HTMLUListElement> | undefined'.
          Type 'ToggleEventHandler<HTMLDivElement>' is not assignable to type 'ToggleEventHandler<HTMLUListElement>'.
            Type 'HTMLDivElement' is missing the following properties from type 'HTMLUListElement': compact, type
  Overload 2 of 2, '(props: DefaultComponentProps<BoxTypeMap<{}, "div", Theme>>): Element | null', gave the following error.
    Type '{ children: ReactNode; ref?: Ref<unknown> | undefined; sx?: SxProps<Theme> | undefined; border?: ResponsiveStyleValue<number | (string & {}) | "inset" | "hidden" | "-moz-initial" | ... 194 more ... | undefined> | ((theme: Theme) => ResponsiveStyleValue<...>); ... 378 more ...; component: string; }' is not assignable to type 'IntrinsicAttributes & BoxOwnProps<Theme> & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & { ...; }, keyof BoxOwnProps<...>>'.
      Property 'component' does not exist on type 'IntrinsicAttributes & BoxOwnProps<Theme> & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & { ...; }, keyof BoxOwnProps<...>>'.
No overload matches this call.
  Overload 1 of 2, '(props: { component: "svg"; } & BoxOwnProps<Theme> & Omit<Omit<SVGProps<SVGSVGElement>, "ref"> & { ref?: ((instance: SVGSVGElement | null) => void | (() => VoidOrUndefinedOnly)) | RefObject<...> | null | undefined; }, keyof BoxOwnProps<...>>): Element | null', gave the following error.
    Type '{ children: Element[]; ref?: Ref<unknown> | undefined; sx?: SxProps<Theme> | undefined; border?: ResponsiveStyleValue<number | (string & {}) | "inset" | "hidden" | "-moz-initial" | ... 194 more ... | undefined> | ((theme: Theme) => ResponsiveStyleValue<...>); ... 381 more ...; xmlns: string; }' is not assignable to type 'Omit<Omit<SVGProps<SVGSVGElement>, "ref"> & { ref?: ((instance: SVGSVGElement | null) => void | (() => VoidOrUndefinedOnly)) | RefObject<...> | null | undefined; }, keyof BoxOwnProps<...>>'.
      Types of property 'onCopy' are incompatible.
        Type 'ClipboardEventHandler<HTMLDivElement> | undefined' is not assignable to type 'ClipboardEventHandler<SVGSVGElement> | undefined'.
          Type 'ClipboardEventHandler<HTMLDivElement>' is not assignable to type 'ClipboardEventHandler<SVGSVGElement>'.
            Type 'HTMLDivElement' is missing the following properties from type 'SVGSVGElement': currentScale, currentTranslate, height, width, and 53 more.
  Overload 2 of 2, '(props: DefaultComponentProps<BoxTypeMap<{}, "div", Theme>>): Element | null', gave the following error.
    Type '{ children: Element[]; ref?: Ref<unknown> | undefined; sx?: SxProps<Theme> | undefined; border?: ResponsiveStyleValue<number | (string & {}) | "inset" | "hidden" | "-moz-initial" | ... 194 more ... | undefined> | ((theme: Theme) => ResponsiveStyleValue<...>); ... 381 more ...; xmlns: string; }' is not assignable to type 'IntrinsicAttributes & BoxOwnProps<Theme> & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & { ...; }, keyof BoxOwnProps<...>>'.
      Property 'component' does not exist on type 'IntrinsicAttributes & BoxOwnProps<Theme> & Omit<Omit<DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & { ...; }, keyof BoxOwnProps<...>>'.

Expected behavior

No TypeScript errors appeared.

I would like to understand clearly how to use Box in MUI v6.

Because in the project I use a lot of places like:

So it will take a lot of time to restructure the whole thing.

Looking forward to suitable suggestions for this situation. Thanks!

sinhpn92 commented 6 days ago

I have the same issue. Waiting for maintainer. Thanks

sjordan2010 commented 2 days ago

I have the same issue. Waiting for maintainer. Thanks

Same here!

bartlangelaan commented 1 day ago

The trick here is to use a type generic:

function Li({ children, ...other }: BoxProps<'li'>) {

function Ul({ children, ...other }: BoxProps<'ul'>) {

function Svg({ children, ...other }: BoxProps<'svg'>) {

See demo: typescript playground

This ensures that TypeScript understands what's going on, and also makes sure that you can, for example, pass the viewBox prop to the Svg component but not to the Li and Ul components.

sjordan2010 commented 9 hours ago

The trick here is to use a type generic:

function Li({ children, ...other }: BoxProps<'li'>) {

function Ul({ children, ...other }: BoxProps<'ul'>) {

function Svg({ children, ...other }: BoxProps<'svg'>) {

See demo: typescript playground

This ensures that TypeScript understands what's going on, and also makes sure that you can, for example, pass the viewBox prop to the Svg component but not to the Li and Ul components.

This works perfectly for me, thank you!