通过模块增强扩展 Material UI 主题无法正常工作

Mik*_*e K 7 javascript typescript reactjs material-ui

我正在尝试Theme使用 Material UI 进行扩展,但它抛出一个错误,说我没有正确扩展它,说,

Property 'layout' is missing in type 'Palette' but required in type 'IPaletteOptions'.
Run Code Online (Sandbox Code Playgroud)

这是我所拥有的:

// src/theme/theme.d.ts
import { Theme } from "@material-ui/core/styles";
import {
  IPaletteOptions,
  PaletteOptions
} from "@material-ui/core/styles/createPalette";

type TLayout = {
  primary: string;
  secondary: string;
};

declare module "@material-ui/core/styles/createPalette" {
  export interface IPaletteOptions extends PaletteOptions {
    layout: TLayout;
  }
}

declare module "@material-ui/core/styles" {
  export interface ITheme extends Theme {
    palette: IPaletteOptions;
  }
}
Run Code Online (Sandbox Code Playgroud)
// src/theme/index.ts
import { createMuiTheme, ITheme } from "@material-ui/core/styles";
import { IPaletteOptions } from "@material-ui/core/styles/createPalette";

export const palette = {
  layout: {
    primary: "#ffffff",
    secondary: "#e4e4e4"
  }
} as IPaletteOptions;

export default createMuiTheme({ palette }) as ITheme;
Run Code Online (Sandbox Code Playgroud)
// src/App.tsx
import React from "react";
import { ThemeProvider, ITheme } from "@material-ui/core";
import theme from "./theme";

import Component from "./Component";

export default function App() {
  return (
    <ThemeProvider<ITheme> theme={theme}>
      <Component />
    </ThemeProvider>
  );
}
Run Code Online (Sandbox Code Playgroud)
import { useTheme } from "@material-ui/core";
import React from "react";

export default React.memo(() => {
  const theme = useTheme(); // <-- this should be of type `ITheme` automatically
                            // If I do useTheme<ITheme>(), it shows property 'layout', but
                            // I shouldn't have to do that, because of the type casting that
                            // I do in App.tsx, where I import and use 'theme' from src/theme/index.ts

  return <div>the layout primary color is {theme.palette.layout.primary}</div>;
});
Run Code Online (Sandbox Code Playgroud)

我在这里做错了什么?我想在我的整个应用程序中使用,除了我添加的内容之外,ITheme这还将扩展基本功能。Theme

酷松本4621h

Ham*_*ame 8

在 Material v5 中你可以扩展CommonColors

declare module "@mui/material/styles/createPalette" {
  interface CommonColors {
    layout: {
      offBlack: string;
      offWhite: string;
    }
  }
}

const colors = createTheme({
  palette: {
    common: {
      layout: {
        offBlack: "#14142B",
        offWhite: "#FCFCFC",
      },
    },
  },
});

// In a component
const useStyles = makeStyles((theme) => ({
  target: {
    backgroundColor: theme.palette.common.layout.offBlack
  }
}));
Run Code Online (Sandbox Code Playgroud)


tmh*_*005 6

我认为覆盖使用您的ITheme类似内容的东西会更方便,如下所示:

theme.d.ts

declare module "@material-ui/core/styles" {
  export interface ITheme extends Theme {
    palette: IPaletteOptions;
  }
  
  // Keep overriding these things in your app
  // In this case returns `ITheme`
  export function createMuiTheme(options?: ThemeOptions, ...args: object[]): ITheme;
  
  // returns `ITheme`
  export function useTheme<T = ITheme>(): T;
}
Run Code Online (Sandbox Code Playgroud)

然后你不再需要在你的theme/index.ts

export default createMuiTheme({ palette });
Run Code Online (Sandbox Code Playgroud)

如果使用useTheme,它应该ITheme按预期返回。

注意:我还更新了codesandbox:https://codesandbox.io/s/charming-pasteur-s6h8v ?file=/src/Component.tsx