Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do makeStyles and createStyles have to be separate (Material UI + TypeScript)?

I've been using this construction that Material UI requires to deal with TypeScript issues a lot and it's really bugging me that every time I want to style a component I need to remember how to combine 2 different functions into something that will yield a hook (I could solve it with a snippet but that just never feels right to me):

const useStyles = makeStyles((theme: Theme) =>
  createStyles({
    ...styles
  })
);

So I tried of course to make it more DRY by just abstracting it away into 1 function but I can't seem to understand how to make the types work for this. Here's my clumsy attempt:

const makeUseStyles = (styleFunc: (th: Theme) => CSSProperties | CreateCSSProperties<{}>) =>
  makeStyles((theme: Theme) => {
    const st = styleFunc(theme);
    return createStyles(st);
  });

This creates 2 problems: createStyles doesn't accept st as an argument:

Type 'unknown' is not assignable to type 'PropsFunc<(value: JSSFontface, index: number, array: JSSFontface[]) => unknown, CreateCSSProperties<(value: JSSFontface, index: number, array: JSSFontface[]) => unknown>>'

And the function returned by makeUseStyles is suddenly expecting a required argument props of type (value: JSSFontface, index: number, array: JSSFontface[]) => unknown.

So I assume, since my attempt failed, that this is why there are 2 separate functions needed in the first place to appease TypeScript but it bothers me a lot that a compiler would dictate the abstractions (which it feels like it does all the time the moment I try to DRY out a bit my styling code). So my question is: why?

like image 299
m3h0w Avatar asked Dec 22 '20 12:12

m3h0w


People also ask

How do you use makeStyles in material UI?

In order to use makeStyles function in your application you will need to import it in the component in where you plan to access the css that results from your makeStyles function. This is assuming you have already installed Material Ui in your project. This is in order for react to recognize it as a styles file.

What can I use instead of makeStyles?

You can use @mui/styles/makeStyles instead. @mui/styles is the legacy styling solution for MUI.


1 Answers

When you use or upgrade to TypeScript version > 3.4 you don’t need to call createStyle. The const assertions that became available in this version can defeat type widening. According to a code comment, the function createStyles will be removed in MaterialUI v5 (though it hasn't been removed from v5.0.0-alpha.23 yet).

I am indeed not experiencing any type widening and this is also confirmed by eps1lon in a github issue comment. The docs should definitely be updated.

like image 166
wedi Avatar answered Sep 28 '22 08:09

wedi