シェルパ・アンド・カンパニー株式会社でプロダクト開発を担当しているペトロフです。開発中に抱えていた課題を踏まえ、Tipsを公開します。
補足
やりたいこと
以下のソースではcolumnsとfilterModelではfieldをstring型で自由に設定できます。しかし、columnsとfilterModelのfield値が合わなければ、フィルタ機能は正常に動作しません。そもそもstring型で自由に文字列を設定できることに違和感がありました。
値が統一されず、無秩序に設定ができてしまうためです。例えば、columns側のfield値だけをfirstNameからfullNameに変更してもエラーにならないため、気付かないうちにデグレード(機能劣化)が発生する可能性があります。今回はcolumnsとfilterModelのfieldをgeneric型で指定し、fieldで特定以外の値を入力されたら型エラーになるようにしたいです。
import { GridColDef, GridFilterModel, DataGridPremium } from "@mui/x-data-grid-premium"; type RowType = { id: number; lastName: string; firstName: string; }; export const DataGridTestComp = () => { const rows = [ { id: 1, lastName: "Snow", firstName: "Jon" }, { id: 2, lastName: "Lannister", firstName: "Cersei" }, { id: 3, lastName: "Lannister", firstName: "Jaime" }, { id: 4, lastName: "Stark", firstName: "Arya" }, { id: 5, lastName: "Targaryen", firstName: "Daenerys" }, ]; const columns: GridColDef<RowType>[] = [ { field: "firstName", headerName: "First name", width: 130 }, { field: "lastName", headerName: "Last name", width: 130 }, ]; const filterModel: GridFilterModel = { items: [ { field: "firstName", operator: "contains", value: "J", }, ], }; return <DataGridPremium rows={rows} columns={columns} filterModel={filterModel} />; };
型定義ファイル
x-data-grid-premium.d.ts等の型定義ファイルを作成します。
以下のようにcolumnの型であるGridColDefと、filterModelの型であるGridFilterModelを拡張し、genericで指定された型をfieldに適用できるようにします。
import { GridBaseColDef as MuiGridBaseColDef, GridActionsColDef as MuiGridActionsColDef, GridSingleSelectColDef as MuiGridSingleSelectColDef, GridValidRowModel as MuiGridValidRowModel, GridFilterItem as MuiGridFilterItem, } from "@mui/x-data-grid-premium"; declare module "@mui/x-data-grid-premium" { export interface GridBaseColDef< R extends MuiGridValidRowModel = MuiGridValidRowModel, V = any, F = V, FieldType extends string = string, > extends MuiGridBaseColDef<R, V, F> { field: FieldType; } export type GridColDef<R extends MuiGridValidRowModel = any, FieldType extends string = string, V = any, F = V> = | GridBaseColDef<R, V, F, FieldType> | MuiGridActionsColDef<R, V, F> | MuiGridSingleSelectColDef<R, V, F>; export type GridFilterModel<FieldType extends string = string> = { items: Array< Omit<MuiGridFilterItem, "field"> & { field: FieldType; } >; }; }
拡張した型を実際に使ってみる
これで完成です。columnやfilterModelのfieldにid,lastName,firstNameの文字以外を入力すると、型エラーが起きるはずです。また、field値を入力する際にVSCodeのIntelliSenseで補完もできます。
import { GridColDef, GridFilterModel, DataGridPremium } from "@mui/x-data-grid-premium"; type RowType = { id: number; lastName: string; firstName: string; }; type FieldKeys = keyof RowType; export const DataGridTestComp = () => { const rows: RowType[] = [ { id: 1, lastName: "Snow", firstName: "Jon" }, { id: 2, lastName: "Lannister", firstName: "Cersei" }, { id: 3, lastName: "Lannister", firstName: "Jaime" }, { id: 4, lastName: "Stark", firstName: "Arya" }, { id: 5, lastName: "Targaryen", firstName: "Daenerys" }, ]; const columns: GridColDef<RowType, FieldKeys>[] = [ { field: "firstNames", headerName: "First name", width: 130 }, { field: "lastName", headerName: "Last name", width: 130 }, ]; const filterModel: GridFilterModel<FieldKeys> = { items: [ { field: "firstNames", operator: "contains", value: "J", }, ], }; return <DataGridPremium rows={rows} columns={columns} filterModel={filterModel} />; };
シェルパ・アンド・カンパニーでは一緒に働く仲間を募集しています。