【问题标题】:How to extend Material-UI Theme with Typescript?如何使用 Typescript 扩展 Material-UI 主题?
【发布时间】:2020-07-22 01:11:24
【问题描述】:

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

如何在此处正确扩展调色板?

【问题讨论】:

标签: javascript reactjs typescript material-ui


【解决方案1】:

解决方案

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 扮演着不同的角色。

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

【讨论】:

  • 感谢您的回答。我无法理解,我想扩展调色​​板(即,我希望它具有原始调色板道具 + 我自己的自定义道具)。那么,为什么要interface ITheme extends Theme { palette: Palette }?还是我应该自己做IPalette 并做interface ITheme extends Theme { palette: Palette<IPalette> }?因为问题是 Typescript 告诉我 chiptype Palette 上不存在,所以我应该自己创建 interface IPalette { chip: { ... } } 吗?
  • @MikeK 已更新。
【解决方案2】:

这可以通过Module Augmentation 轻松解决:

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;
      };
    };
  }
}

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2019-07-15
  • 1970-01-01
  • 2018-02-19
  • 2020-07-20
  • 1970-01-01
  • 1970-01-01
  • 2021-08-10
  • 2022-10-24
相关资源
最近更新 更多