Material UIのTextFieldで’Type ‘”filled”‘ is not assignable to type ‘”outlined””.が発生する際の対処

2022.02.09

こんにちは、CX事業本部 IoT事業部の若槻です。

今回は、Material UIのTextFieldでType 'Type '"filled"' is not assignable to type '"outlined"'.'という型エラーが発生する際の対処についてです。

Material UIのTextFieldとは

React向けのUIライブラリであるMaterial UIでは、様々なMaterial Designベースのコンポーネントを使用できます。

そのコンポーネントのうちの一つであるTextFieldを使用すると、入力フォームやテーブルのフィルター画面などに利用できるコンポーネントを簡単に導入できます。

このTextFieldでは、variantフィールドを指定することにより、コンポーネントの見た目を変えることができます。

import * as React from 'react';
import Box from '@mui/material/Box';
import TextField from '@mui/material/TextField';

export default function BasicTextFields() {
  return (
    <Box
      component="form"
      sx={{
        '& > :not(style)': { m: 1, width: '25ch' },
      }}
      noValidate
      autoComplete="off"
    >
      <TextField id="outlined-basic" label="Outlined" variant="outlined" />
      <TextField id="filled-basic" label="Filled" variant="filled" />
      <TextField id="standard-basic" label="Standard" variant="standard" />
    </Box>
  );
}

そして今回事象が発生したのはこのvariantフィールドの扱いにおいてでした。

環境

事象が発生した環境は次のようになります。

@material-ui/core@4.11.0
@types/react@16.9.41
react@16.13.1
typescript@3.7.5

ここで注意点として、従来のMaterial UI(v4)は、2021年にMUI(Material UI v5)に置き換えられました。

The package names have changed in v5, which is a breaking change.

そして従来の@material-ui/coreはすでにメンテナンスが停止されています。よって新規プロジェクトでMaterial UIを導入する場合は、@material-ui/coreではなく、@mui/material を使うようにしましょう。

TextFieldのvariantフィールドで型エラーが発生する

さて前節の環境でTextFieldを使用して次のようなコンポーネントを作成しました。簡易化していますが、TextFieldのvariantをstateに応じてfilledoutlinedで切り替えるようにしています。

import React from 'react';
import TextField from '@material-ui/core/TextField';
import Grid from '@material-ui/core/Grid';
import { makeStyles } from '@material-ui/core/styles';

const useStyles = makeStyles({
  gridItem: {
    marginTop: '10px',
  },
});

let state = true;

const App: React.FC = () => {
  const classes = useStyles();

  return (
    <Grid
      container
      alignItems='center'
      justify='center'
      direction='column'
      style={{ minHeight: '100vh' }}
    >
      <Grid item className={classes.gridItem}>
        <TextField id='field1' label='Field 1' variant='outlined' />
      </Grid>
      <Grid item className={classes.gridItem}>
        <TextField id='field2' label='Field 2' variant='outlined' />
      </Grid>
      <Grid item className={classes.gridItem}>
        <TextField
          id='field3'
          label='Field 3'
          variant={state ? 'filled' : 'outlined'}
        />
      </Grid>
    </Grid>
  );
};

export default App;

このコンポーネントを含めたアプリをnpm run startでローカル実行したところ、ビルド時に次のようなエラーが発生してしましいます。

Type '{ id: string; label: string; defaultValue: string; variant: "filled" | "outlined"; required: true; InputProps: { readOnly: boolean; }; }' is not assignable to type '(IntrinsicAttributes & StandardTextFieldProps) | (IntrinsicAttributes & FilledTextFieldProps) | (IntrinsicAttributes & OutlinedTextFieldProps)'.
  Type '{ id: string; label: string; defaultValue: string; variant: "filled" | "outlined"; required: true; InputProps: { readOnly: boolean; }; }' is not assignable to type 'OutlinedTextFieldProps'.
    Types of property 'variant' are incompatible.
      Type '"filled" | "outlined"' is not assignable to type '"outlined"'.
        Type '"filled"' is not assignable to type '"outlined"'.  TS2322

解決

TextFieldのPropsは'(IntrinsicAttributes & StandardTextFieldProps) | (IntrinsicAttributes & FilledTextFieldProps) | (IntrinsicAttributes & OutlinedTextFieldProps)となるところ、variant: "filled" | "outlinedの部分が上手く型付けできていないようです。

本来は問題無さそうですがバグのような動作です。

方法1

無理やりですがanyにキャストすることによりエラーを回避することができました。

      <Grid item className={classes.gridItem}>
        <TextField
          id='field3'
          label='Field 3'
          variant={flag ? 'filled' : ('outlined' as any)}
        />
      </Grid>

アプリも起動できています。

しかし環境によってはLintツールに引っかかるかも知れません。

方法2

TypeScriptをアップデートすることでも回避できました。今回は3.7.5から4.5.5にアップデートすることによりエラーは発生しなくなりました。

typescript@4.5.5

おわりに

Material UIのTextFieldでType 'Type '"filled"' is not assignable to type '"outlined"'.'という型エラーが発生する際の対処についてでした。

解決まで少々時間を費やしてしまったのですが、明らかに怪しい動作に遭遇した際はライブラリのアップデートも選択肢に入れてすぐに試せると良いなと思いました。

参考

以上