如何使用Typescript扩展材质-UI主题?

fxnxkyjh  于 2022-11-18  发布在  TypeScript
关注(0)|答案(3)|浏览(160)

Typescript总是抱怨调色板中缺少某些属性。如果我添加//@ts-ignore,我的应用程序就能正常工作,但显然我想避免这种情况。我是Typescript的新手,以下是我尝试过的。

import createMuiTheme, { ThemeOptions, Theme } from '@material-ui/core/styles/createMuiTheme';
import { PaletteOptions } from '@material-ui/core/styles/createPalette';

interface IPaletteOptions extends PaletteOptions {
    chip: {
      color: string,
      expandIcon: {
        background: string,
        color: string,
      },
    },
}
interface ITheme extends Theme {
  palette: IPaletteOptions,
}

const theme: ITheme = createMuiTheme({
  typography: {
    fontWeightMedium: 600,
    fontFamily: ['Open Sans', 'Arial', 'sans-serif'].join(','),
  },
  palette: {
    primary: {
      main: '#43C099',
    },
    secondary: {
      main: '#7AF3CA',
    },
    chip: {
      color: '#C2C3C6',
      expandIcon: {
        background: '#808183',
        color: '#FFFFFF',
      },
    },
  },
} as ThemeOptions);

这将引发一个错误,

Type 'Theme' is not assignable to type 'ITheme'.
  Types of property 'palette' are incompatible.
    Property 'chip' is missing in type 'Palette' but required in type 'IPaletteOptions

这对我来说是一个令人困惑的错误,因为我在任何地方都没有使用Palette类型。
如何在此处正确扩展调色板?

tp5buhyn

tp5buhyn1#

这可以通过模块扩充更容易地解决:
MUI第5版
material-ui.d.ts

import { PaletteOptions } from "@mui/material/styles/createPalette";

declare module "@mui/material/styles/createPalette" {
  export interface PaletteOptions {
    chip: {
      color: string;
      expandIcon: {
        background: string;
        color: string;
      };
    };
  }
}

MUI第4版
material-ui.d.ts

import { PaletteOptions } from "@material-ui/core/styles/createPalette";

declare module "@material-ui/core/styles/createPalette" {
  export interface PaletteOptions {
    chip: {
      color: string;
      expandIcon: {
        background: string;
        color: string;
      };
    };
  }
}
vmpqdwk3

vmpqdwk32#

溶液

import createMuiTheme, { Theme, ThemeOptions } from "@material-ui/core/styles/createMuiTheme";
import { Palette } from "@material-ui/core/styles/createPalette";

interface IPalette extends Palette {
  xxx: {}
}
interface ITheme extends Theme {
  palette: IPalette;
}
interface IThemeOptions extends ThemeOptions {
  palette: IPalette;
}

const theme = createMuiTheme({
  palette: {
    ...
    xxx: {}                                        // Type been checked
  }
} as IThemeOptions)                                // Use customized ThemeOptions type

const useStyles = makeStyles((theme: ITheme) => ({ // Use customized Theme type
  root: {
    color: theme.palette.xxx                       // Work with no type error
  }
}));

参考
如果我们看一下createMuiTheme.d.ts

import { Palette, PaletteOptions } from './createPalette';

export interface ThemeOptions {
  palette?: PaletteOptions;
  ...
}

export interface Theme {
  palette: Palette;
  ...
}

export default function createMuiTheme(options?: ThemeOptions, ...args: object[]): Theme;

我们会发现ThemeThemeOptions扮演着不同的角色。

  • 主题:返回类型
  • 主题选项:参数类型
zmeyuzjn

zmeyuzjn3#

在React typescript中,当在子组件中使用主题时,必须声明变量是ThemeOptions的类型。

import { ThemeOptions } from '@mui/material';

const ChildComponent: React.FC<Props> = (Props) => {
const theme:ThemeOptions  = useTheme();
  const theme:ThemeOptions = React.useContext(ThemeContext); 
return ()}

相关问题