Static Typing for MUI React Data Grid Columns

John Reilly October 7, 2024
Source
The MUI X Data Grid is a really handy component for rendering tabular data in React applications. But one thing that is not immediately obvious is how to use TypeScript to ensure that the columns you pass to the component are correct. This post will show you how to do that. Why does it matter? Well look at this screenshot of the Data Grid with incorrect column names: Interestingly, the User column is blank. Given the code, we'd probably expect to see a users name there. Let's take look at the code for that screenshot: The issue is that the field property in the column definition is incorrect. It should be username not user-name. We know that, but the TypeScript compiler doesn't. And the Data Grid doesn't appear to know that either; there's no error in the console surfacing an issue. Using TypeScript to extract type information from the rows It's possible to use TypeScript to ensure that the columns you pass to the Data Grid are valid. What we want, is TypeScript to say: "Hey, you've passed the wrong column name to the Data Grid" (in it's own inimitable way). We can do that. What we want to do, is use TypeScript to analyse the rows array and extract type information. We can do that like so: The ValidRow type is the type of an element in the rows array: The ValidField type is derived from the ValidRow type; it is the keys of the ValidRow type. So, the ValidField type is: Finally, we can create a type that represents a column with a valid field in the form of the ColumnWithValidField type: The type above says explicitly that the field property of a column must be one of the keys of the ValidRow type. This is the type information we require to ensure that the columns we pass to the Data Grid are correct. Applying the type information to the columns Now we have this type information, we can then use that information to type the columns array. We can do that like so: Whereas previously the columns array was not explicitly typed. Now it is with the satisfies operator. (For an excellent explanation of satifies read Matt Pocock's post.) We are saying that columns is an array of GridColDef and that the field property of each element in the array is definitely one of the provided fields in the rows data. We need both of these conditions to be true: - Using GridColDef ensures that the general columns schema matches what the Data Grid component needs. - Using ColumnWithValidField ensures that the field property of each column is correct; based upon the rows field. Let's validate this approach works, trying to use our buggy input with this new approach: We can now see an error from the TypeScript compiler in VS Code: Type '"user-name"' is not assignable to type '"id" | "username" | "age"'. Did you mean '"username"'? It's even an actionable error, suggesting the correct field name! Putting it all together Here's the full code (with the error corrected): With this approach, you can be confident that the columns you pass to the Data Grid are correct. This is a great way to ensure that your code is correct and that you are using the Data Grid component as intended. The importance of memoizing columns The MUI docs say: > The columns prop should keep the same reference between two renders. The columns are designed to be definitions, to never change once the component is mounted. Otherwise, you take the risk of losing elements like column width or order. You can create the array outside the render function or memoize it. My own experience has been that I noticed no ill effects on my own use cases by not memoizing. When I asked the question I was advised this was still important when you use a big number of columns and rows. To apply that to the example we've been working with, it would look like this:

Discussion in the ATmosphere

Loading comments...