-
-
Notifications
You must be signed in to change notification settings - Fork 32.3k
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
[typescript] createStyles and improved WithStyles helpers #11609
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really good work!
I am not a fan of having to use the identity function in TS to have good type inference, but we tried long enough to not use this approach I guess 🙂
@@ -5,45 +5,129 @@ Have a look at the [Create React App with TypeScript](https://github.com/mui-org | |||
|
|||
## Usage of `withStyles` | |||
|
|||
The usage of `withStyles` in TypeScript can be a little tricky, so it's worth showing some examples. You can first call `withStyles()` to create a decorator function, like so: | |||
The usage of `withStyles` in TypeScript can be a little tricky for a number of reasons, but |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there something missing after the "but"? 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops 😬
bar: boolean; | ||
} | ||
|
||
const styles = (theme: Theme) => createStyles({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe first styles
then Props
so you know what typeof styles
refers to? Also "declare before use" lint error! 😁
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Types can refer to things in any order, and at least in my code I tend to put all type declarations at the top of the file. But I don't feel too strongly about it.
describe('createStyles', () => { | ||
it('is the identity function', () => { | ||
const styles = {}; | ||
assert.strictEqual(createStyles(styles), styles); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a little nit-picking, but does strictEqual
compare properties or checks that the passed in arguments are the same "pointer". Meaning, the result of createStyles
and styles
is the same reference.
If not, we could add another tests that just check for ===
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
strictEqual
uses ===
👍 .
export interface WithStyles<ClassKey extends string = string> extends Partial<WithTheme> { | ||
classes: ClassNameMap<ClassKey>; | ||
} | ||
export type WithStyles<T extends string | StyleRules | StyleRulesCallback> = Partial<WithTheme> & { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is absolutely awesome and a good use case for conditional types 🤩
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing the default = string
is a breaking change though?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@geirsagberg right you are. I've opened #11808 to fix that.
@@ -0,0 +1,5 @@ | |||
// @flow | |||
|
|||
export default function createStyles(s: Object) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's funny, life is a circle, we had this function in v1.0.0-alpha.x
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't know that... did it serve the same purpose?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nop, we used it to perform some operations on the styles.
describe('createStyles', () => { | ||
it('is the identity function', () => { | ||
const styles = {}; | ||
assert.strictEqual(createStyles(styles), styles); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
strictEqual
uses ===
👍 .
guttered: theme.mixins.gutters({ | ||
'&:hover': { | ||
textDecoration: 'none', | ||
}, | ||
}), | ||
listItem: { | ||
'&:hover $listItemIcon': { | ||
visibility: 'inherit', | ||
// visibility: 'inherit', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On purpose?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, will restore.
withStyles()
complains unless usingas
#10995 by adding the helper functioncreateStyles
which is basically what was suggested in [typescript] add sample with return types #11512 (comment). It doesn't actually "do anything", it's just the identity function, but it's useful for guiding TypeScript inference, particularly for styles which depend on the theme.WithStyles
type operator to allow takingtypeof styles
as input, which allows declaring prop types with injected style types like so:See the updated TypeScript guide for more about how to use these.