This issue applies to the v1-beta
branch. The typescript type definitions of StyleRules
and Theme
are not compatible and cause a typescript type conflict.
As an example consider the following typical case:
import { withStyles, Theme, StyleRulesCallback } from 'material-ui/styles';
const styles: StyleRulesCallback = (theme: Theme) => ({
root: theme.typography.button,
});
const Component = (props: any) => <p className={props.classes.root}>Test</p>;
export default withStyles(styles)(Component);
The constant styles
should correctly type check.
The constant styles
does not type check correctly. The problem is an incompatibility between the types StyleRules
(defined in src/styles/withStyles.d.ts
) and Theme
(defined in src/styles/createMuiTheme.d.ts
):
{root: theme.typography.button}
is supposed to be of type StyleRule
(because styles
is declared to be StyleRulesCallback
as expected by the call to withStyles
)fontWeight
in a StyleRule
object is defined to be as defined in React.CSSProperties
, i.e., "initial" | "inherit" | "unset" | "normal" | "bold" | "bolder" | "lighter" | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900
theme.typography.button
is of type TypographyStyle
, whose fontWeight
property is of type number | string
| Tech | Version |
|--------------|---------|
| Material-UI | v1-beta |
| React | 15.6 |
A possible solution would be to reference the types in React.CSSProperties
for the entries in TypographyStyle
and FontStyle
. This would conform to the type definition of StyleRule
.
I provided a fix for this issue. See #8199.
@TorstenStueber Hi Torsten, I'd like to ask you after seeing your #8199 PR: is there any consideration why you didn't change fontWeightLight
, fontWeightRegular
, and fontWeightMedium
as well? So it would be like
export interface FontStyle {
fontFamily: React.CSSProperties['fontFamily'];
fontSize: React.CSSProperties['fontSize'];
fontWeightLight: React.CSSProperties['fontWeight'];
fontWeightRegular: React.CSSProperties['fontWeight'];
fontWeightMedium: React.CSSProperties['fontWeight'];
}
?
Because I encounter a similar issue when using theme.typography.fontWeightLight
. But after changing fontWeightLight
type to React.CSSProperties['fontWeight']
it typechecks.
I believe I have the same similar issue with fontWeight
. Following code:
const decorate = withStyles(() => {
const style = {
root: {
fontWeight: 700,
},
};
return style;
});
give typescript error:
[ts]
Argument of type '() => { root: { fontWeight: number; }; }' is not assignable to parameter of type 'Record<"root", Partial> | StyleRulesCallback<"root">'.
Type '() => { root: { fontWeight: number; }; }' is not assignable to type 'StyleRulesCallback<"root">'.
Type '{ root: { fontWeight: number; }; }' is not assignable to type 'Record<"root", Partial>'.
Types of property 'root' are incompatible.
Type '{ fontWeight: number; }' is not assignable to type 'Partial'.
Types of property 'fontWeight' are incompatible.
Type 'number' is not assignable to type '700 | "initial" | "inherit" | "unset" | "normal" | "bold" | "bolder" | "lighter" | 100 | 200 | 30...'.
As I understand this has to do with the way Typescript interpretes type of fontWeight
as number.
I know I can fix that by using as
and specifing type e.g. fontWeight: 700 as React.CSSProperties["fontWeight"]
but this kind of silly.
Isn't there a better way?
@apieceofbart I guess you should try hinting style
with StyleRules
const decorate = withStyles(() => {
const style: StyleRules = {
root: {
fontWeight: 700,
},
};
return style;
});
It should work
@dewey92 thanks, I ended up doing it this way, this is by far the cleanest way.
@dewey92 thanks! that's very clean if you wrap it in a high order function like this:
// stylesFactory.ts
export default stylesFn => {
const stylesResult = (theme, props) => {
const styles = stylesFn(theme, props);
return styles as StyleRules;
};
return stylesResult as StyleRulesCallback;
};
then you can use
const styles = stylesFactory(theme => ({}))
const StyledComponent = withStyles(styles)(Component);
without typing problems
Most helpful comment
@apieceofbart I guess you should try hinting
style
withStyleRules
It should work