最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to use Material UI custom variants in React with Typescript - Stack Overflow

programmeradmin3浏览0评论

Example with error: =/src/App.tsx

I am trying to extend from Mui's types to add a few more variants. I'm already extending from Muis base props. interface IText extends TypographyProps {

I'm after avoiding having to manage all of the types that Mui have already defined. In this exact case it is here:

"h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "subtitle1" | "subtitle2" | "body1" | "body2" | "caption" | "button" | "overline"

In theory, the final outcome of the props would be:

 "inherit" | "caption12r" | "caption12ruc" | "caption12buc" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "subtitle1" | "subtitle2" | "body1" | "body2" | "caption" | "button" | "overline" 

Error

TS2769: No overload matches this call.   Overload 1 of 2, '(props: { component: ElementType<any>; } & SystemProps<Theme> & { align?: "right" | "left" | "inherit" | "center" | "justify" | undefined; children?: ReactNode; ... 6 more ...; variantMapping?: Partial<...> | undefined; } & CommonProps & Omit<...>): Element', gave the following error.     Type '{ "data-name": string; component?: string | undefined; variant?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "subtitle1" | "subtitle2" | "body1" | "body2" | "caption" | "button" | "overline" | ... 4 more ... | undefined; ... 352 more ...; onTransitionEndCapture?: TransitionEventHandler<...> | undefined; }' is not assignable to type '{ component: ElementType<any>; }'.       Types of property 'component' are incompatible.         Type 'string | undefined' is not assignable to type 'ElementType<any>'.           Type 'undefined' is not assignable to type 'ElementType<any>'.   Overload 2 of 2, '(props: DefaultComponentProps<TypographyTypeMap<{}, "span">>): Element', gave the following error.     Type '{ "data-name": string; component?: string | undefined; variant?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "subtitle1" | "subtitle2" | "body1" | "body2" | "caption" | "button" | "overline" | ... 4 more ... | undefined; ... 352 more ...; onTransitionEndCapture?: TransitionEventHandler<...> | undefined; }' is not assignable to type '{ align?: "right" | "left" | "inherit" | "center" | "justify" | undefined; children?: ReactNode; classes?: Partial<TypographyClasses> | undefined; ... 5 more ...; variantMapping?: Partial<...> | undefined; }'.       Types of property 'variant' are incompatible.         Type '"h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "subtitle1" | "subtitle2" | "body1" | "body2" | "caption" | "button" | "overline" | "inherit" | "caption12r" | "caption12ruc" | "caption12buc" | undefined' is not assignable to type '"h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "subtitle1" | "subtitle2" | "body1" | "body2" | "caption" | "button" | "overline" | "inherit" | undefined'.

Code where extending is failing

import React from "react";
import { Typography as MUITypography, TypographyProps } from "@mui/material";
import { OverridableStringUnion } from "@mui/types";
import { Variant } from "@mui/material/styles/createTypography";
import { TypographyPropsVariantOverrides } from "@mui/material/Typography/Typography";

interface IText extends TypographyProps {
  component?: string;
  variant?: OverridableStringUnion<
    Variant | "inherit" | "caption12r" | "caption12ruc" | "caption12buc",
    TypographyPropsVariantOverrides
  >;
}

I have also tried to extend it via a tsModules with:

export interface EleMuiVariantOverrides {
  'icon': true;
}

declare module "@mui/material/Button/Button" {
  interface ButtonPropsVariantOverrides extends EleMuiVariantOverrides {}
}

Example with error: https://codesandbox.io/s/flamboyant-lederberg-w16pio?file=/src/App.tsx

I am trying to extend from Mui's types to add a few more variants. I'm already extending from Muis base props. interface IText extends TypographyProps {

I'm after avoiding having to manage all of the types that Mui have already defined. In this exact case it is here:

"h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "subtitle1" | "subtitle2" | "body1" | "body2" | "caption" | "button" | "overline"

In theory, the final outcome of the props would be:

 "inherit" | "caption12r" | "caption12ruc" | "caption12buc" | "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "subtitle1" | "subtitle2" | "body1" | "body2" | "caption" | "button" | "overline" 

Error

TS2769: No overload matches this call.   Overload 1 of 2, '(props: { component: ElementType<any>; } & SystemProps<Theme> & { align?: "right" | "left" | "inherit" | "center" | "justify" | undefined; children?: ReactNode; ... 6 more ...; variantMapping?: Partial<...> | undefined; } & CommonProps & Omit<...>): Element', gave the following error.     Type '{ "data-name": string; component?: string | undefined; variant?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "subtitle1" | "subtitle2" | "body1" | "body2" | "caption" | "button" | "overline" | ... 4 more ... | undefined; ... 352 more ...; onTransitionEndCapture?: TransitionEventHandler<...> | undefined; }' is not assignable to type '{ component: ElementType<any>; }'.       Types of property 'component' are incompatible.         Type 'string | undefined' is not assignable to type 'ElementType<any>'.           Type 'undefined' is not assignable to type 'ElementType<any>'.   Overload 2 of 2, '(props: DefaultComponentProps<TypographyTypeMap<{}, "span">>): Element', gave the following error.     Type '{ "data-name": string; component?: string | undefined; variant?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "subtitle1" | "subtitle2" | "body1" | "body2" | "caption" | "button" | "overline" | ... 4 more ... | undefined; ... 352 more ...; onTransitionEndCapture?: TransitionEventHandler<...> | undefined; }' is not assignable to type '{ align?: "right" | "left" | "inherit" | "center" | "justify" | undefined; children?: ReactNode; classes?: Partial<TypographyClasses> | undefined; ... 5 more ...; variantMapping?: Partial<...> | undefined; }'.       Types of property 'variant' are incompatible.         Type '"h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "subtitle1" | "subtitle2" | "body1" | "body2" | "caption" | "button" | "overline" | "inherit" | "caption12r" | "caption12ruc" | "caption12buc" | undefined' is not assignable to type '"h1" | "h2" | "h3" | "h4" | "h5" | "h6" | "subtitle1" | "subtitle2" | "body1" | "body2" | "caption" | "button" | "overline" | "inherit" | undefined'.

Code where extending is failing

import React from "react";
import { Typography as MUITypography, TypographyProps } from "@mui/material";
import { OverridableStringUnion } from "@mui/types";
import { Variant } from "@mui/material/styles/createTypography";
import { TypographyPropsVariantOverrides } from "@mui/material/Typography/Typography";

interface IText extends TypographyProps {
  component?: string;
  variant?: OverridableStringUnion<
    Variant | "inherit" | "caption12r" | "caption12ruc" | "caption12buc",
    TypographyPropsVariantOverrides
  >;
}

I have also tried to extend it via a tsModules with:

export interface EleMuiVariantOverrides {
  'icon': true;
}

declare module "@mui/material/Button/Button" {
  interface ButtonPropsVariantOverrides extends EleMuiVariantOverrides {}
}
Share Improve this question asked Apr 8, 2022 at 12:42 Jamie HutberJamie Hutber 28.1k54 gold badges192 silver badges311 bronze badges 6
  • 1 Just to make sure, your module is in a .d.ts file and is referenced in tsconfig via types or include? – Anthony Ma Commented Apr 9, 2022 at 14:48
  • Cheers Anthony, if you check out the sandbox I've added the theme.d.ts file which has the declarations and still getting it: codesandbox.io/s/flamboyant-lederberg-w16pio?file=/src/App.tsx Any ideas? – Jamie Hutber Commented Apr 9, 2022 at 21:23
  • In your example you were declaring @mui/material/Typography but importing from @mui/material/Typography/Typography, maybe that's the problem? CodeSandbox didn't show me any errors so I can't really troubleshoot any further. – Anthony Ma Commented Apr 10, 2022 at 23:16
  • Ye, indeed. I also thought the same thing and had played around with it. However I can see the sandbox no longer has TS errors. I will import these changes into my component library and see if I can get it working smoothly. – Jamie Hutber Commented Apr 11, 2022 at 0:12
  • Why not use storybook for custom inputs and extending MUI. – Ritik Banger Commented Apr 11, 2022 at 6:05
 |  Show 1 more comment

2 Answers 2

Reset to default 14 +250

To extend Typography variants you can do so:

import React from "react";
import {
  Typography,
  TypographyProps,
  createTheme,
  ThemeOptions,
  ThemeProvider
} from "@mui/material";
import { TypographyOptions } from "@mui/material/styles/createTypography";

declare module "@mui/material/Typography" {
  interface TypographyPropsVariantOverrides {
    caption12r: true;
  }
}

interface ExtendedTypographyOptions extends TypographyOptions {
  caption12r: React.CSSProperties;
}

const theme = createTheme({
  typography: {
    caption12r: {
      color: "red"
    }
  } as ExtendedTypographyOptions
} as ThemeOptions);

const Text = (props: TypographyProps) => {
  return <Typography {...props} data-name="CLText" />;
};

export default function App() {
  return (
    <ThemeProvider theme={theme}>
      <div className="App">
        <Text variant="caption12r">Jamie</Text>
      </div>
    </ThemeProvider>
  );
}

For more details please refer to MUI documentation.

In your codesandbox I can see also an attempt to use extended variants for a Button; sorry but I can't help on that.

to avoid interface ExtendedTypographyOptions:

import React from 'react';
import {
    Typography,
    TypographyProps,
    createTheme,
    ThemeProvider
} from '@mui/material';


declare module '@mui/material' {
  interface TypographyPropsVariantOverrides {
      caption12r: true;
  }

  interface TypographyClasses {
      caption12r: string;
  }
}
declare module '@mui/material/styles' {
  // allow configuration using `createTheme`
  interface TypographyVariantsOptions {
      caption12r?: React.CSSProperties;
  }

  interface TypographyVariants {
      caption12r: React.CSSProperties;
  }

}


const theme = createTheme({
    typography: {
        caption12r: {
            color: 'red'
        }
    },
    components: {
        MuiTypography: {
            caption12r: {
            // ...style overrides
            }
        }
    }
});

const Text = (props: TypographyProps) => {
    return <Typography {...props} data-name='CLText' />;
};

export default function App() {
    return (
        <ThemeProvider theme={theme}>
            <div className='App'>
                <Text variant='caption12r'>Jamie</Text>
            </div>
        </ThemeProvider>
    );
}

发布评论

评论列表(0)

  1. 暂无评论