React

React TypeScript で flexWrap、flexDireciton がエラー: CSSProperties を指定して回避

皆さまこんにちは、ウチイダです。

表題の件でエラーに遭遇したので、対策をメモしておきます。

環境

  • React 18.2.0
  • Typescript 4.9.3
  • @types/React 18.0.26
  • Vite 3.2.5

事象

CSS in JS でスタイルを記述した際、flexWrapを含んだオブジェクトを変数に格納してから、style 属性に渡すとエラーが出ます。

style 属性にそのままオブジェクトを書いた場合はエラーになりません。

export const FlexStyleError = () => {
	const elementStyle = {
		flexWrap: 'wrap'
	};

	return (
		<>
			<div style={{ flexWrap: 'wrap' }}>これはセーフ</div>
			<div style={elementStyle}>オブジェクトで渡すとエラー</div>
		</>
	)
}

エラーメッセージはこんな感じ。flexWrapの値として、string 型は渡せないよ~と言われてます。

Type '{ flexWrap: string; }' is not assignable to type 'Properties<string | number, string & {}>'.
  Types of property 'flexWrap' are incompatible.
    Type 'string' is not assignable to type 'FlexWrap | undefined'.ts(2322)
index.d.ts(1869, 9): The expected type comes from property 'style' which is declared here on type 'DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>'

ちなみに、flexDirection でも同じエラーが起こります。

原因:csstype の型定義が使えてないから?

flexWrap とflexDirection には、それぞれFlexWrap と FlexDirection という専用の型があります。

  export type FlexWrap = Globals | "nowrap" | "wrap" | "wrap-reverse";

指定の文字列リテラルのUnion型として定義されていて、オブジェクトに渡した内容が正しく型を認識できてないぽいです。

解決方法:推論に任せず指定する

原因は分かったけど、よい解決策がわかりません。

というわけでエラーメッセージで検索したら、GitHubでissue が立っていました。

flexDirection is not assignable to CSSProperties 

まさにこれだ~と思いながらレスを追っていくと、いくつか対策が書かれていました。

要するに、型推論がちゃんとされなくてエラーになっちゃってるので、明確に指定すれば大丈夫ということです。

個人的には、styleに渡すオブジェクト全体に、React.CSSProperties を指定するのがいいかなと思いました。

flexDirection 以外のプロパティで問題が出ても、対処できそうです。

export const FlexStyleError = () => {
	// const elementStyle = {
	// React.CSSProperties 型を指定
	const elementStyle: React.CSSProperties = {
		flexWrap: 'wrap'
	};

	return (
		<>
			<div style={{ flexWrap: 'wrap' }}>これはセーフ</div>
			<div style={elementStyle}>オブジェクトで渡すとエラー</div>
		</>
	)
}

エラーも出なくなったし、そのうえ、プロパティのヒントも出してくれるように!

ReactCSSProperties を型指定することで、ヒントが正確に出る

CSS in JS を使うときは、型指定するとよい感じにプロパティが書けそうです。

以上です。

あなたのお役に立てればうれしいです。

ESLint の初期設定時、Airbnb のスタイルガイドが選択肢に表示されない – 手動インストールする

みなさんこんにちは、ウチイダです。

最近フロントエンドをきちんと学ぼうと思って、Reactのキャッチアップを進めています。

せっかくなのでTypeScriptで開発するようにしているのですが、その際の環境構築でつまづくことがあったので書き留めておきます。

環境

  • Windows 11 21H2
  • WSL2 Ubuntu20.04
  • Node.js v18.12.0
  • npm 8.19.3

事象:Airbnbのスタイルガイドを選択できない

JavaScriptのスタイルガイドとしてポピュラーなものに、Airbnb が作成しているものがあります。

これをESLintでのチェックに利用しようと思いました。

ESLint を導入する際、以下のコンフィグファイルの初期化コマンド を実行します。

$ npm init @eslint/config 

手順を説明しているページなどを見ると、スタイルガイドの選択時にAirbnbが出てくるようだったのですが、ウチイダの環境だとそれが表示されませんでした。

選択肢が2つしか表示されない

原因:AirbnbのスタイルガイドがTypeScriptに対応していないため

初期設定を行うコマンド eslint-config で行われた修正が原因でした。

ここで、TypeScriptに標準で対応していないスタイルガイドを表示しないように変更されていました。

https://github.com/eslint/create-config/pull/33

自分の作業手順漏れを疑っていたのですが、仕様変更だったんですね。。。

ちなみに、これは最近参加しているコミュニティの方が調べて教えてくれました。感謝!

対応:手動でAirbnbのスタイルガイドを追加する

自動でインストールしてくれないのは仕方ないので、とりあえずeslintrc の生成を済ませて、あとからAirbnbのスタイルガイドを読み込ませるように設定していきます。

1. eslintrc を生成する

スタイルガイドでStandard を選択して、設定を進めます。

次に「依存パッケージをインストールするか」を聞かれるので、no を選んでおきます。

Standardのスタイルガイドのパッケージを後から削除するのであれば、yes でもよいです。

$ npm init @eslint/config
✔ How would you like to use ESLint? · style

✔ What type of modules does your project use? · esm

✔ Which framework does your project use? · react

✔ Does your project use TypeScript? · No / Yes

✔ Where does your code run? · browser

✔ How would you like to define a style for your project? · guide

✔ Which style guide do you want to follow? · standard-with-typescript

✔ What format do you want your config file to be in? · JavaScript

Checking peerDependencies of eslint-config-standard-with-typescript@latest
Local ESLint installation not found.
The config that you've selected requires the following dependencies:

eslint-plugin-react@latest eslint-config-standard-with-typescript@latest @typescript-eslint/eslint-plugin@^5.0.0 eslint@^8.0.1 eslint-plugin-import@^2.25.2 eslint-plugin-n@^15.0.0 eslint-plugin-promise@^6.0.0 typescript@*

✔ Would you like to install them now? · No / Yes

A config file was generated, but the config file itself may not follow your linting rules.
Successfully created .eslintrc.cjs file in /home/y-uchiida/develop/eslint_airbnb_none

2. Airbnb のスタイルガイドのパッケージを追加する

npm で、スタイルガイドのパッケージを導入します。

Airbnb のTypeScript のスタイルガイドは本家の設定の拡張なので、本家も含めてインストールします。

$ npm install --save-dev eslint-config-airbnb eslint-config-airbnb-typescript

3. eslintrc にスタイルガイドを読み込ませる

eslintrc を編集して、Airbnb のスタイルガイドを読み込みさせます。

    "extends": [
        "plugin:react/recommended",
        // "standard-with-typescript" // standard スタイルガイドは使わないので消す
        'airbnb', // 追加
        'airbnb-typescript' // 追加
    ],

ちなみに、Reactのプロジェクトかそうでないかによって、利用するパッケージが違うので注意が必要です。

詳しくはGitHubのREADMEをご確認ください…

https://github.com/iamturns/eslint-config-airbnb-typescript#setup

まとめ

ESLintの初期設定を自分でやったことがなかった&比較的最近の変更で、見つかる情報と齟齬があった(Airbnbが出てくると書いてあるものが多かった)ことでハマってしまいました。

ツールチェイン周りのキャッチアップは大変です…

ちなみに、ウチイダと同じ疑問を持った人がGitHubでissueを立てていました。

やり方を覚えてしまえばなんてことはないですが、手作業インストールするのちょっとだけ面倒ですね…

上記のissueの中で、「将来的に –config オプションを実装する予定があるので、それができたら簡単になるよ」といった旨のコメントがついていました。

https://github.com/eslint/create-config/issues/35#issuecomment-1216457480

早く利用できるようになるといいですね。

それでは以上となります。あなたのお役に立てれば幸いです。