What is the necessity behind keeping makeStyles and createStyles separate in Material UI with TypeScript?

Dealing with TypeScript issues in Material UI has been a frequent task for me, and I find it frustrating that styling components requires combining two different functions to create a hook every time. While I could use a snippet to simplify the process, it never quite feels right to me. Here is an example of the common construction I use:

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

In an attempt to make this process more DRY, I tried abstracting it into one function, but encountered difficulty in making the types work correctly. Here is my attempt:

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

This approach raised two problems: createStyles did not accept st as an argument, resulting in an error message:

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

Furthermore, the function returned by makeUseStyles suddenly expected a required argument props of type

(value: JSSFontface, index: number, array: JSSFontface[]) => unknown
.

My failed attempt made me question why there is a need for two separate functions to satisfy TypeScript requirements, and why the compiler seems to dictate the abstractions when trying to streamline styling code. So, I wonder, why is this necessary?

Answer №1

After upgrading to TypeScript version > 3.4, there is no longer a need to call createStyle. The introduction of const assertions in this release can prevent type widening. According to a note in the code, the function createStyles will eventually be phased out in MaterialUI v5 (although it is still present in v5.0.0-alpha.23).

I have personally not encountered any issues with type widening, and this has also been confirmed by eps1lon in a comment on GitHub. It seems like the documentation needs to be updated to reflect these changes.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How can I add multiple filters to a Kendo Grid?

Is there a way to include two separate filter fields for date filtering in Kendo Grid UI? Currently, the method I am using only allows for one date filter to be displayed. filterable: { ui: function (element: any) { element.ken ...

What specific type of useRef should I use to reference a callback function?

I have been exploring the method outlined by Dan Abramov for creating a custom hook to handle basic setInterval functionality. However, I am facing challenges while trying to type it in TypeScript. Specifically, I am unsure about what should be the type of ...

Issue NG1006: Class has two conflicting decorators applied

I encountered an issue while compiling my project: PS C:\Users\hasna\Downloads\A La Marocaine git - Copie\ALaMarocaineFinal\frontend\src\app> ng serve Compiling @angular/forms : es2015 as esm2015 An unhandled exc ...

Having trouble with resolving 'react-transition-group' in MUI IconButton?

I can't seem to shake this persistent error: ./node_modules/@mui/material/ButtonBase/TouchRipple.js Module not found: Can't resolve 'react-transition-group' in '#/node_modules/@mui/material/ButtonBase' I've diligently fo ...

Creating an adaptable image with CSS or Material UI

Is it possible to create a responsive image that shifts from the top right position to the bottom as the size decreases? I've been using Material UI but haven't found any guidance on how to achieve this. .my-photo{ height: 300px; positio ...

Adding files to an Angular ViewModel using DropzoneJS

I am facing a challenge in extracting file content and inserting it into a specific FileViewModel. This is necessary because I need to bundle all files with MainViewModel which contains a list of FileViewModel before sending it from the client (angular) to ...

Enhance your user interface by adding a tooltip above a button

I am currently working on creating a button that can copy content from a variable into the clipboard using TypeScript and Material-UI. Here is what I have tried: const [copySuccess, setCopySuccess] = useState(''); const copyToClipBoard = async ( ...

Checking constructor arguments and code style issues

I need to ensure that the constructor parameter is validated correctly when an instance of a class is created. The parameter must be an object that contains exactly all the properties, with the appropriate types as specified in the class definition. If t ...

"Step-by-Step Guide: Displaying a New Component When a Table Row is

I am currently working with an API to populate a table within the router outlet, but I would like to know how I can load a different component that displays the details of a selected row. For example, if the table contains a list of equipment, I want to be ...

The VSCode's intellisense for Angular Material fails to function effectively

In the midst of my project on Angular version 13, I have successfully installed Angular Material using the command below: ng add @angular/material The package has been properly included in the node_modules folder. However, when working with TypeScript ...

typescript create object with immutable property already set

Can you create an object literal in JavaScript and define its interface with read-only properties simultaneously? For instance let obj = { readonly prop1: 'hello', readonly prop2: 'world' } ...

The statement "import React from 'react'" is automatically removed by VS Code

When I need to remove unused modules that I no longer need, I frequently use shift + alt + o. This method has worked perfectly for me in the past when editing .tsx files. However, recently, VS Code seems to be removing the import React from 'react&ap ...

The parameter type 'Object' cannot be assigned to the parameter type 'JSON' in the HttpClient GET method

Hey there! Currently, I'm deep into developing an Angular 6 + Flask application and I've encountered a bit of a snag: Error TS2345: Argument of type 'Object' is not assignable to parameter of type 'JSON'. This issue arises w ...

Surprising fraction of behavior

Looking for some clarification on the types used in this code snippet: interface UserDTO { id: string; email: string; } const input: Partial<UserDTO> = {}; const userDTO: Partial<UserDTO> = { id: "", ...input }; const email = us ...

Tips for incorporating themes into custom functional components' styles

A certain error "TypeError:undefined has no properties" is displayed when I attempt to compile the app. Despite this error, I am trying to render styled components into the grid tags using the function-based component method. const styles = theme =&g ...

Ways to transmit information or notifications from a service to a component

Currently, I am utilizing Angular 6 and have the upload file control on three different screens (three various components). Each of these screens calls the same method UploadFile(). The main issue arises when I need to make any changes to this method, as ...

Utilizing Database values in .css files with Vue.js and TypeScript

I am currently working on extracting a color value from the database and applying it to my external .css files. I have searched extensively online but haven't found a satisfactory solution yet. Here is the JavaScript code snippet: createBackgroundHead ...

What is the reason for the lack of overlap between types in an enum?

I'm having trouble understanding why TypeScript is indicating that my condition will always be false. This is because there is no type overlap between Action.UP | Action.DOWN and Action.LEFT in this specific scenario. You can view the code snippet and ...

Alert: User is currently engaging in typing activity, utilizing a streamlined RXJS approach

In my current project, I am in the process of adding a feature that shows when a user is typing in a multi-user chat room. Despite my limited understanding of RXJS, I managed to come up with the code snippet below which satisfies the basic requirements for ...

Customize the initial view of the Material UI pagination component by specifying a new number value to

In the Material UI library, I am having trouble customizing the pagination component. Here is the code snippet for reference: <Pagination count={10} /> The default pagination displays from 1 to 5, but I want it to show from 1 to 4 as shown below. ...