TypeScript 2.6 -> material-ui 1.0.0-beta.24 withStyles with react-router withRouter -> 属性 'classes' 类型缺失
TypeScript 2.6 -> material-ui 1.0.0-beta.24 withStyles with react-router withRouter -> Property 'classes' is missing in type
我可以毫无问题地同时使用高阶组件 withStyles
和 withRouter
,但升级到最新版本时出现错误。
https://reactjs.org/docs/higher-order-components.html
使用的包:
"@types/react-router": "^4.0.20",
"@types/react-router-dom": "^4.2.3",
"material-ui": "^1.0.0-beta.24",
"react-router": "^4.2.0",
"react-router-dom": "^4.2.2",
我一直在查看两个库的测试,一个一个地实施它们不是问题:
https://github.com/mui-org/material-ui/blob/v1-beta/test/typescript/styles.spec.tsx
然而,当我尝试将它们组合在一起时,我得到了这个错误:
TS2322: Type '{ text: "foo"; }' is not assignable to type
'IntrinsicAttributes & Pick &
WithStyles, "text" ...'. Type '{ text: "foo"; }' is
not assignable to type 'Pick &
WithStyles, "text" | "classes" | "theme">'. Property
'classes' is missing in type '{ text: "foo"; }'.
代码,仅在<DecoratedComponent text="foo" />;
行出现错误
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import * as ReactRouter from 'react-router';
import { Redirect, Route, Switch, withRouter, RouteComponentProps } from 'react-router-dom';
import Grid from 'material-ui/Grid';
import { withStyles, WithStyles, StyleRulesCallback } from 'material-ui/styles';
import { CustomTheme } from 'Features/Client/Styles/MainTheme';
import 'Styles/App.css';
import * as es6ObjectAssign from 'es6-object-assign';
es6ObjectAssign.polyfill();
type withStyleProps = 'mainStyle' | 'innerStyle';
const styles: StyleRulesCallback<withStyleProps> = (theme: CustomTheme) => ({
mainStyle: {
backgroundColor: '#F7F7F7',
minHeight: '100vh',
} as React.CSSProperties,
innerStyle: {
padding: theme.spacing.small,
paddingTop: 0,
paddingBottom: 0,
maxWidth: '90rem',
margin: '0 auto',
} as React.CSSProperties,
});
interface IProps {
text: string;
}
interface IState {
}
class App extends React.Component<IProps & WithStyles<withStyleProps>, IState> {
constructor(props: IProps & WithStyles<withStyleProps>) {
super(props);
this.state = {
};
}
render() {
const { classes } = this.props;
return (
<div className={classes.mainStyle}>
<div className={classes.innerStyle}>
<DecoratedComponent text="foo" />;
</div>
</div>
);
}
}
export default withStyles(styles)(App);
const DecoratedComponent = withStyles(styles)(withRouter(
class extends React.Component<IProps & RouteComponentProps<{}> & WithStyles<withStyleProps>> {
render() {
const { classes, text } = this.props;
return <div className={classes.mainStyle}>{text}</div>;
}
}
));
更新:
将使用构造函数且不想复制和粘贴的组件的解决方案IProps2 & RouteComponentProps<IProps> & WithStyles<withStyleProps>
interface IProps2 {
text: string;
}
type Props2 = IProps2 & RouteComponentProps<{}> & WithStyles<withStyleProps>;
const DecoratedComponent = withRouter(withStyles(styles)(
class extends React.Component<Props2> {
render() {
const { classes, text } = this.props;
return <div className={classes.mainStyle}>{text}</div>;
}
}
));
原文:
现在设法通过将 withRouter
放在前面和 withStyles
后面来解决它。
const DecoratedComponent = withRouter(withStyles(styles)(
class extends React.Component<IProps & RouteComponentProps<IProps> & WithStyles<withStyleProps>> {
render() {
const { classes, text } = this.props;
return <div className={classes.mainStyle}>{text}</div>;
}
}
));
我可以毫无问题地同时使用高阶组件 withStyles
和 withRouter
,但升级到最新版本时出现错误。
https://reactjs.org/docs/higher-order-components.html
使用的包:
"@types/react-router": "^4.0.20",
"@types/react-router-dom": "^4.2.3",
"material-ui": "^1.0.0-beta.24",
"react-router": "^4.2.0",
"react-router-dom": "^4.2.2",
我一直在查看两个库的测试,一个一个地实施它们不是问题:
https://github.com/mui-org/material-ui/blob/v1-beta/test/typescript/styles.spec.tsx
然而,当我尝试将它们组合在一起时,我得到了这个错误:
TS2322: Type '{ text: "foo"; }' is not assignable to type 'IntrinsicAttributes & Pick & WithStyles, "text" ...'. Type '{ text: "foo"; }' is not assignable to type 'Pick & WithStyles, "text" | "classes" | "theme">'. Property 'classes' is missing in type '{ text: "foo"; }'.
代码,仅在<DecoratedComponent text="foo" />;
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import * as ReactRouter from 'react-router';
import { Redirect, Route, Switch, withRouter, RouteComponentProps } from 'react-router-dom';
import Grid from 'material-ui/Grid';
import { withStyles, WithStyles, StyleRulesCallback } from 'material-ui/styles';
import { CustomTheme } from 'Features/Client/Styles/MainTheme';
import 'Styles/App.css';
import * as es6ObjectAssign from 'es6-object-assign';
es6ObjectAssign.polyfill();
type withStyleProps = 'mainStyle' | 'innerStyle';
const styles: StyleRulesCallback<withStyleProps> = (theme: CustomTheme) => ({
mainStyle: {
backgroundColor: '#F7F7F7',
minHeight: '100vh',
} as React.CSSProperties,
innerStyle: {
padding: theme.spacing.small,
paddingTop: 0,
paddingBottom: 0,
maxWidth: '90rem',
margin: '0 auto',
} as React.CSSProperties,
});
interface IProps {
text: string;
}
interface IState {
}
class App extends React.Component<IProps & WithStyles<withStyleProps>, IState> {
constructor(props: IProps & WithStyles<withStyleProps>) {
super(props);
this.state = {
};
}
render() {
const { classes } = this.props;
return (
<div className={classes.mainStyle}>
<div className={classes.innerStyle}>
<DecoratedComponent text="foo" />;
</div>
</div>
);
}
}
export default withStyles(styles)(App);
const DecoratedComponent = withStyles(styles)(withRouter(
class extends React.Component<IProps & RouteComponentProps<{}> & WithStyles<withStyleProps>> {
render() {
const { classes, text } = this.props;
return <div className={classes.mainStyle}>{text}</div>;
}
}
));
更新:
将使用构造函数且不想复制和粘贴的组件的解决方案IProps2 & RouteComponentProps<IProps> & WithStyles<withStyleProps>
interface IProps2 {
text: string;
}
type Props2 = IProps2 & RouteComponentProps<{}> & WithStyles<withStyleProps>;
const DecoratedComponent = withRouter(withStyles(styles)(
class extends React.Component<Props2> {
render() {
const { classes, text } = this.props;
return <div className={classes.mainStyle}>{text}</div>;
}
}
));
原文:
现在设法通过将 withRouter
放在前面和 withStyles
后面来解决它。
const DecoratedComponent = withRouter(withStyles(styles)(
class extends React.Component<IProps & RouteComponentProps<IProps> & WithStyles<withStyleProps>> {
render() {
const { classes, text } = this.props;
return <div className={classes.mainStyle}>{text}</div>;
}
}
));