Skip to content
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

[DataGrid] Narrow down GridColDef['type'] #11270

Merged
merged 13 commits into from
Dec 6, 2023

Conversation

cherniavskii
Copy link
Member

@cherniavskii cherniavskii commented Dec 1, 2023

Closes #9735

Changelog

  • The GridColDef['type'] has been narrowed down to only accept the built-in column types.
    TypeScript users need to use the GridColDef interface when defining columns:

    // πŸ›‘ `type` is inferred as `string` and is too wide
    const columns = [{ type: 'number', field: 'id' }];
    <DataGrid columns={columns} />;
    
    // βœ… `type` is `'number'`
    const columns: GridColDef[] = [{ type: 'number', field: 'id' }];
    <DataGrid columns={columns} />;
    
    // βœ… Alternalively, `as const` can be used to narrow down the type
    const columns = [{ type: 'number' as const, field: 'id' }];
    <DataGrid columns={columns} />;

@cherniavskii cherniavskii added breaking change component: data grid This is the name of the generic UI component, not the React module! v7.x labels Dec 1, 2023
@mui-bot
Copy link

mui-bot commented Dec 1, 2023

```tsx
// πŸ›‘ `type` is casted to `string` which is too wide
const columns = [{ type: 'number', id: 'field' }];
<DataGrid columns={columns} />;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like the error here though:

I thought I could improve this by making GridColDef a union discriminated by the type field, but type is optional and it doesn't seem to work as expected from discriminated union :/

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any ideas how we can improve this for TS users?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want autocomplete without this problem, you can use field: GridColType | string instead of field: GridColType.
But of course you are loosing the actual type checking.

Otherwise, people need to set type: 'number' as const or columns: GridColDef.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just realized that the code snippet above was wrong.
What I wanted to show here is this error:

Otherwise, people need to set type: 'number' as const or columns: GridColDef.

Yes, this is fine, my concern is the error when the type is inferred as string.
I find this part confusing:

Types of property 'type' are incompatible.
Type 'string' is not assignable to type '"singleSelect"'.

Ideally, it should be:

Types of property 'type' are incompatible.
Type 'string' is not assignable to type "string" | "number" | "date" | "dateTime" | "boolean" | "singleSelect" | "actions".

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh right,
AFAIK, it's due to the structure of your type
You are doing:
GridColDef = { type: 'number', ...rest } | { type: 'string', ...rest }
To have the correct autocompletion you would need to have something like:
GridColDef<T extends 'number' | 'string'> = { type: T' } & T extends 'string' ? { ...restString } : { ...restNumber }
But I suppose it's not a trivial change.

Other than that, they might be some hack you could do, but I don't know them :p

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I guess this is just the nature of unions in TS.
When columns is not explicitly typed, TS requires it to be compatible with all the subtypes of the GridColDef union.
Here's a minimal TS playground reproducing the issue: https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgOJWAEwEJwM4QDCA9gDYAiEMyA3gFDKPJgCeADhAFzIDkeYGEAHMeAbgZMYwCKUzd+goeIC+dOqEixEKdFgCCCMMGIg8JClVoTGrDtx6IjJvGOvIpMucgWglboRBgBk6m3AAUAJTIALwAfMhwICwA2gC6Kmq2OhiY5pTU0Wg5uAR5lgA+RfqGxqZlMOJ0mBAIpHBQKAjOYO4g4V2kAK4AtqFVuWT5UXEJSY1dpj0DI6YxtMzsXLw+wjwANO7Ssvb4mKc8yMriMCBhy6N4EUA

@cherniavskii cherniavskii marked this pull request as ready for review December 1, 2023 19:46
@@ -9,7 +9,7 @@ export const GRID_DETAIL_PANEL_TOGGLE_FIELD = '__detail_panel_toggle__';
export const GRID_DETAIL_PANEL_TOGGLE_COL_DEF: GridColDef = {
...GRID_STRING_COL_DEF,
field: GRID_DETAIL_PANEL_TOGGLE_FIELD,
type: 'detailPanelToggle',
type: 'string',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to have a type dedicated to all the interactive columns (all the toggles, the actions, etc...)
Because "string" is not super coherent IMHO

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They're extending the string column definition anyway, it's just that they don't render the string as cell content πŸ™‚
Adding another type would make it appear in the autocomplete for the users, I would rather not add it until there are more reasons to do so.

Copy link
Contributor

@romgrk romgrk Dec 4, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we've already debated on it, but I'll repeat anyway here for the record: I think we should add a "custom" type for the columns that don't fit with any real datatype. It's more explicit than having our special columns be "string". I don't mind that it appears on autocomplete, we can add a note about it on our types table, some users may also have custom columns that don't represent a datatype.

We can also assign it more sensible default behaviors, such as ignoring it for filtering & quickfiltering purposes, and that can improve performance a bit.

edit: btw if we extend GRID_STRING_COL_DEF, the type: 'string' here is redundant with the same field declared in GRID_STRING_COL_DEF

Copy link
Contributor

@romgrk romgrk Dec 4, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But regardless if we add a different "custom" type, we should probably do something like this for our custom columns:

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we've already debated on it, but I'll repeat anyway here for the record: I think we should add a "custom" type for the columns that don't fit with any real datatype. It's more explicit than having our special columns be "string"

Yes that's basically what I had in mind

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added the custom column type, but did not create GRID_CUSTOM_COL_DEF:

  • Every custom column type has a different set of flags and there's no general rule for that: some columns have the column menu, some columns have row grouping disabled, etc. It's better to have all the flags explicitly provided in each column definition.
  • Not all custom columns extend the string column definition - see
    export const GRID_CHECKBOX_SELECTION_COL_DEF: GridColDef = {
    ...GRID_BOOLEAN_COL_DEF,
    field: GRID_CHECKBOX_SELECTION_FIELD,

What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, that makes sense πŸ‘

```tsx
// πŸ›‘ `type` is casted to `string` which is too wide
const columns = [{ type: 'number', id: 'field' }];
<DataGrid columns={columns} />;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want autocomplete without this problem, you can use field: GridColType | string instead of field: GridColType.
But of course you are loosing the actual type checking.

Otherwise, people need to set type: 'number' as const or columns: GridColDef.

Copy link
Contributor

@romgrk romgrk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've left my opinion about the custom columns type, I disagree with making those "string" but I'm not going to block the PR on that.

However if you could standardize these, either convert all to "string" or remove all (last option prefered):
image

@cherniavskii cherniavskii enabled auto-merge (squash) December 6, 2023 18:05
@cherniavskii cherniavskii merged commit f65114a into mui:next Dec 6, 2023
15 checks passed
@cherniavskii cherniavskii deleted the grid-col-def-type branch December 6, 2023 19:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking change component: data grid This is the name of the generic UI component, not the React module! v7.x
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[DataGrid] Improve typing of GridColDef['type']
4 participants