{
"$type": "site.standard.document",
"canonicalUrl": "https://johnnyreilly.com/posts/static-typing-for-mui-react-data-grid-columns",
"description": "The MUI React Data Grid can be used with static typing to ensure the columns you pass to the component are correct. This post will show you how to do that.",
"path": "/posts/static-typing-for-mui-react-data-grid-columns",
"publishedAt": "2024-10-07T00:00:00.000Z",
"site": "at://did:plc:yy3apqjlms24kso7ahn7lbmb/site.standard.publication/3mova7c4nho2b",
"tags": [
"react",
"typescript",
"mui"
],
"textContent": "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.\n\nWhy does it matter? Well look at this screenshot of the Data Grid with incorrect column names:\n\n\n\nInterestingly, the User column is blank. Given the code, we'd probably expect to see a users name there.\n\nLet's take look at the code for that screenshot:\n\nThe 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.\n\nUsing TypeScript to extract type information from the rows\n\nIt'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.\n\nWhat we want to do, is use TypeScript to analyse the rows array and extract type information. We can do that like so:\n\nThe ValidRow type is the type of an element in the rows array:\n\nThe ValidField type is derived from the ValidRow type; it is the keys of the ValidRow type. So, the ValidField type is:\n\nFinally, we can create a type that represents a column with a valid field in the form of the ColumnWithValidField type:\n\nThe 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.\n\nApplying the type information to the columns\n\nNow we have this type information, we can then use that information to type the columns array. We can do that like so:\n\nWhereas 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.)\n\nWe are saying that columns is an array of GridColDef<ValidRow> 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:\n\n- Using GridColDef<ValidRow> ensures that the general columns schema matches what the Data Grid component needs.\n- Using ColumnWithValidField ensures that the field property of each column is correct; based upon the rows field.\n\nLet's validate this approach works, trying to use our buggy input with this new approach:\n\nWe 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!\n\nPutting it all together\n\nHere's the full code (with the error corrected):\n\nWith 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.\n\nThe importance of memoizing columns\n\nThe MUI docs say:\n\n> 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.\n\nMy 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:",
"title": "Static Typing for MUI React Data Grid Columns"
}