-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Better typescript and withstyles decorate #9105
Conversation
Duplicate of #8829? |
I was in favor of #8829 but I've since discovered that it still doesn't solve all of the problems. Specifically, you frequently need to specify the union of class keys when calling const decorate = withStyles(theme => ({
parent: {
display: 'flex',
margin: theme.spacing.unit * 3,
},
child: {
justifyContent: 'center',
},
})) Due to a design limitation of TypeScript, the compiler can't infer the correct type here and it fails to type check. To fix it you need to explicitly provide the union of class keys when invoking const decorate = withStyles<'parent' | 'child'>(theme => ({
parent: {
display: 'flex',
margin: theme.spacing.unit * 3,
},
child: {
justifyContent: 'center',
},
})) which of course defeats the entire point of #8829 and this PR, which is to be able to automatically derive these class keys from the style object . However in conjunction with #8819 it would make more sense, because you'd be able to assist inference in the other direction, from the inside out: const decorate = withStyles(theme => ({
parent: style({
display: 'flex',
margin: theme.spacing.unit * 3,
}),
child: style({
justifyContent: 'center',
}),
})) For this reason I think my preference would be to accept both #8819 and #8829. The current situation of having to maintain both a style object as well as a union of its keys is pretty annoying. |
Maybe we should pin @pelotom answer to that so we don't have this PR a third time? 😓 |
@pelotom This plan sounds good to me. |
I am not of fan of both 🤔 Especially #8819. I think adding a layer of indirection should almost never be the answer and in this case adding #8829 goes a bit in the same direction. It seems like people just want less to write, which I can relate too, but it's kinda like with tl;dr; That said: @pelotom is completely right. We should do something. Of the three I like @Bnaya solution the most, even though it not fully solves the issues described in #8819 + #8829. @pelotom @oliviertassinari Sorry to the latency, I am stuck in a pile of work / organizing Christmas parties, the later on is a first-world problem I guess (but on a side note, if any of you ever is visiting Freiburg, ping me and lets get some coffee! ...or maybe give a talk at the local meetup. |
If it's helpful to anyone while this is being sorted out, here's a hack that work with the current code: const styles = ({ spacing }: Theme) => ({
root: {
padding: spacing.unit,
}
});
const stylesReturnTypeHack = true ? null as never : styles(null as any);
type WithStylesHack = WithStyles<keyof typeof stylesReturnTypeHack>;
const decorate = withStyles(styles);
const DecoratedClass = decorate(
class extends React.Component<WithStylesHack> {
render() {
return (
<div className={this.props.classes.root}></div>
);
}
}
); |
I think we should close this. #9272 outlines a simpler way in the common case to avoid the need to maintain an explicit union of class keys. Any objections? |
Well, feel free to do so :) ill check #9272 |
@Bnaya it has limitations for sure; it's only a good for application developers with a single global theme. |
Ok, closing this for now... |
With this typings change you can do: