如何为“ material-ui”组件的className选择正确的类型?

时间:2019-04-23 04:46:09

标签: reactjs typescript material-ui

我在material-ui中将typescript用于React应用。 material-ui提供了withStyles,它们通过其className注入到组件中。但是我不知道如何声明它的类型。下面是示例代码:

import * as React from 'react';
import Grid from '@material-ui/core/Grid';
import { withStyles, createStyles } from '@material-ui/core/styles';

const BackgroundPanelStyles = createStyles({
  root: {
    height: '16rem',
  }
});

const BackgroundPanelComponent = ({classes}: {classes: typeof BackgroundPanelStyles}) => {
  return (
    <Grid container className={classes.root}>

    </Grid>
  )
};

export const BackgroundPanel = withStyles(BackgroundPanelStyles)(BackgroundPanelComponent);

我在BackgroundPanelStyles对象中定义了样式,并将其用作组件属性类型。但是我遇到了错误。在打字稿中定义属性类型的正确方法是什么?

 Argument of type '({ classes }: { classes: Record<"root", CSSProperties>; }) => Element' is not assignable to parameter of type 'ComponentType<ConsistentWith<{ classes: Record<"root", CSSProperties>; }, { classes: Record<"root", string>; }>>'.
  Type '({ classes }: { classes: Record<"root", CSSProperties>; }) => Element' is not assignable to type 'FunctionComponent<ConsistentWith<{ classes: Record<"root", CSSProperties>; }, { classes: Record<"root", string>; }>>'.
    Types of parameters '__0' and 'props' are incompatible.
      Type 'ConsistentWith<{ classes: Record<"root", CSSProperties>; }, { classes: Record<"root", string>; }> & { children?: ReactNode; }' is not assignable to type '{ classes: Record<"root", CSSProperties>; }'.
        Types of property 'classes' are incompatible.
          Type 'Record<"root", string>' is not assignable to type 'Record<"root", CSSProperties>'.
            Types of property 'root' are incompatible.
              Type 'string' is not assignable to type 'CSSProperties'.

2 个答案:

答案 0 :(得分:0)

经过一番搜索,我发现道具必须是interface Props { classes: { [className in keyof typeof BackgroundPanelStyles]: string } };

下面的代码按预期工作:

import * as React from 'react';
import Grid from '@material-ui/core/Grid';
import { withStyles, createStyles } from '@material-ui/core/styles';

const BackgroundPanelStyles = createStyles({
  root: {
    height: '16rem',
  }
});

interface Props { classes: { [className in keyof typeof BackgroundPanelStyles]: string } };

const BackgroundPanelComponent = ({ classes }: Props) => {
  return (
    <Grid container className={classes.root}>

    </Grid>
  )
};

export const BackgroundPanel = withStyles(BackgroundPanelStyles)(BackgroundPanelComponent);

答案 1 :(得分:0)

您可以使用@ material-ui / core / styles中的 w ithStyles, W ithStyles和StyleRulesCallback来创建HOC。在此处阅读有关withstyles的更多信息

正在运行的演示here

import * as React from "react";
import Grid from "@material-ui/core/Grid";
import {
  StyleRulesCallback,
  withStyles,
  WithStyles
} from "@material-ui/core/styles";

export interface BackgroundPanelComponentOwnProps {
  someProp: Boolean;
}

export type withStyleProps = "someClass" | "anotherClass";
export type BackgroundPanelComponentStyleProps = WithStyles<withStyleProps>;
export type BackgroundPanelComponentProps = BackgroundPanelComponentOwnProps &
  BackgroundPanelComponentStyleProps;

const BackgroundPanelComponent: React.SFC<BackgroundPanelComponentProps> = props => {
  return (
    <Grid container={true} className={props.classes.someClass}>
      <Grid className={props.classes.anotherClass}>Hello</Grid>
    </Grid>
  );
};

const styles: StyleRulesCallback<withStyleProps> = () => ({
  someClass: {
    height: "16rem"
  },
  anotherClass: {
    color: "red"
  }
});

export const StyledBackgroundPanelComponent = withStyles(styles)(
  BackgroundPanelComponent
);