この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、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に応じてfilled
とoutlined
で切り替えるようにしています。
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"'.'
という型エラーが発生する際の対処についてでした。
解決まで少々時間を費やしてしまったのですが、明らかに怪しい動作に遭遇した際はライブラリのアップデートも選択肢に入れてすぐに試せると良いなと思いました。
参考
以上