

export default function createStyles<K extends string = string>(styles: StyleRules<K>): StyleRules<K>;
| Tech | Version |
|--------------|---------|
| Material-UI | v1.2.0 |
| TypeScript | v2.8.3 |
@chilbi You'd have to do something like this for now:
const styles: StyleRulesCallback = ({ palette, spacing, typography }) => createStyles<StyleRules>({
...
});
or
const styles = ({ palette, spacing, typography }: Theme) => createStyles<StyleRules>({
...
});
@pelotom Any better suggestions ?馃槃
@franklixuefei if you go the createStyles<StyleRules> route, you lose the autocomplete on the this.props.classes
@BrendonSled I think it's one way or the other. For now I don't have a solution that's easy enough to cover both cases. The only solution I can think of is to explicitly pass in the keys, like WithStyles<'rule1' | 'rule2'>, rather than using typeof styles as the type param of WithStyles. However, this is ugly.
Also, you can put the keys into the type param of StyleRules, like StyleRules<'rule1' | 'rule2'>, and still use typeof styles in WithStyles. Essentially, both solutions are the same, and, ugly.
It's kind of like a "chicken and egg` problem. See below for a possible solution.
type classList =
| 'root'
| 'rule1'
| 'rule2'
;
const styles = ({ palette, spacing, typography }: Theme) => createStyles<StyleRules<classList>>({
root: {...}, // intellisense enabled
rule1: {...},
rule2: {...}
});
...
classes.root; // intellisense enabled
...
The whole purpose of the createStyles(...) function is to infer your class keys from what you put in ..., so there's no point ever providing a type parameter to it. If you're going to explicitly provide the class keys from the outside, just do
const styles: StyleRulesCallback<ClassKey> = ({ palette, spacing, typography }) => ({
...
});
@pelotom using the createStyles(...) function breaks autocomplete inside the CSS properties. Which is the issue outlined above by the OC.
A temporary workaround I've found if you want autocomplete on the CSS properties and inferred class keys is to just add CSSProperties to each class key, like so
const styles = (theme) => ({
root: {...} as CSSProperties,
rule1: {...} as CSSProperties,
});
...
classes.root; // intellisense enabled
@BrendonSled I like your workaround. as CSSProperties can be annoying, but at least we don't have to specify classList anymore.
To me, TBH, the autocompletion inside the CSS properties is more important.
I wish type widening had never been invented.
@BrendonSled yep, I was just responding to later comments. This seems like maybe an issue worth raising with the TypeScript team? I would think that if the as CSSProperties annotation is sufficient to get autocompletion then it should also work with createStyles.
I actually did the following
const styles = (theme: Theme) => createStyles<StyleRules>(
{
classname: {
somecssprop: "cssvalue"
},
}
);
interface IComponentOwnProps {
classes: {[T in keyof ReturnType<typeof styles>]: T};
}
@chilbi This should be resolved with #12456 which was released in 1.5.0.
Edit:
It seems like this is indeed a bug in typescript. Microsoft/TypeScript#22077 looks like the same issue.
We have a fix for now but if this question comes up again we can forward to the typescript issues.
Most helpful comment
@pelotom using the
createStyles(...)function breaks autocomplete inside the CSS properties. Which is the issue outlined above by the OC.A temporary workaround I've found if you want autocomplete on the CSS properties and inferred class keys is to just add
CSSPropertiesto each class key, like so