Slide 1

Slide 1 text

導入してみたい typescript-eslintのルール Yud ai Su zu ki / @yu b0n 2024.08.28

Slide 2

Slide 2 text

自己紹介 2022年3月 atama plus株式会社 入社 スクラムチームでエンジニアリングや プロダクトマネジメントに取り組みつつ、 フロントエンド刷新プロジェクトのオーナー、 フロントエンドギルド (≒委員会) のマスター を務める。 Y udai Suz uki @yub0 n 2

Slide 3

Slide 3 text

会社紹介

Slide 4

Slide 4 text

ⓒ atama plus Inc. 4 AI教材「atama+」を開発。 一人ひとりの 「得意」「苦手」を分析し、 学習をパーソナライズします。

Slide 5

Slide 5 text

ⓒ atama plus Inc. ミッション 5 「基礎学力」の習得 「基礎学力」の習得 「社会でいきる力」の習得 学習を一人ひとり最適化し、「基礎学力」を最短で身につけ、 そのぶん増える時間で、「社会でいきる力」を伸ばす。 そんな新しい学びを数億人の生徒に届け、社会のまんなかから変えていきます。

Slide 6

Slide 6 text

本題

Slide 7

Slide 7 text

ⓒ atama plus Inc. その開発環境、 ESLint入ってますか? 7

Slide 8

Slide 8 text

ⓒ atama plus Inc. ESLintとは • https://eslint.org/ • JavaScriptのコードをチェックしてくれる静的解析ツール • コードが正しく書かれているか、バグがないかなどを自動で見つけて教えてく れる メリット • コードの書き方を揃えて認知負荷を軽減できる • 不要なコードを消してレビュー工数を削減できる • 踏みやすい落とし穴を回避してバグ発生を防止できる • モジュールの境界・依存関係を明確にして治安を維持できる 導入してみたいtypescript-eslintのルール 8

Slide 9

Slide 9 text

ⓒ atama plus Inc. typescript-eslint • https://typescript-eslint.io/ • ESLintのデフォルトのJavaScript parserはTypeScript 固有の構文をネイティブ に読み取ることができない • =TypeScriptの構文を解析できるようにしたESLint atama plusにおいてもESLintルールの強化に向けて調査を行ったので、 みなさんが「知らなかったけど、導入してみたくなる...!」 というラインを狙ってtypescript-eslintのルールをご紹介していこうと思います。 導入してみたいtypescript-eslintのルール 9

Slide 10

Slide 10 text

コードの書き方を揃えて 認知負荷を軽減できるルール

Slide 11

Slide 11 text

ⓒ atama plus Inc. コードの書き方を揃えて認知負荷を軽減できるルール prefer-includes 文字列や配列に値が含まれているかの確認の際に indexOfで判定する方法とincludesで判定する方法があります。 導入してみたいtypescript-eslintのルール 11 array.indexOf(value) !== -1; array.includes(value); →includesはES2016に追加されたメソッドで、 (好みもあるかもしれませんが一般的に)includesを利用したほうが 直感的でわかりやすいです。

Slide 12

Slide 12 text

ⓒ atama plus Inc. コードの書き方を揃えて認知負荷を軽減できるルール prefer-includes 文字列や配列に任意の値が含まれているかの確認の際に ES2016から追加されたincludesを利用することを強制できます。 導入してみたいtypescript-eslintのルール 12 incorrect array.indexOf(value) !== -1; str.indexOf(value) !== -1; correct array.includes(value); str.includes(value);

Slide 13

Slide 13 text

ⓒ atama plus Inc. コードの書き方を揃えて認知負荷を軽減できるルール その他のおすすめ prefer-find 配列の中で条件に一致する最初の項目を返す際に filter()[0]ではなくfindで行うことを強制できます。 prefer-optional-chain nullableなオブジェクトからプロパティを取り出す際に、 論理積演算子(&&)ではなくオプショナルチェーン(?.)を利用することを強制でき ます。 導入してみたいtypescript-eslintのルール 13

Slide 14

Slide 14 text

不要なコードを消して レビュー工数を削減できるルール

Slide 15

Slide 15 text

ⓒ atama plus Inc. 不要なコードを消してレビュー工数を削減できるルール no-unnecessary-condition 以下のコードではitemsがT[]型なのでnullableな値にはなり得ないですが、 if文で不要なチェックを行っています。 →おそらく配列が空かどうかのチェックをしたかったが、 誤った実装をしています。 導入してみたいtypescript-eslintのルール 15 function head(items: T[]) { if (items) { return items[0].toUpperCase(); } }

Slide 16

Slide 16 text

ⓒ atama plus Inc. 不要なコードを消してレビュー工数を削減できるルール no-unnecessary-condition 型情報を元にif文での不要な分岐をチェックできます。 今回の例では本来やりたかった配列が空かどうかのチェックが 間違っていたことに気づくことができます。 導入してみたいtypescript-eslintのルール 16 incorrect function head(items: T[]) { if (items) { return items[0].toUpperCase(); } } correct function head(items: T[]) { if (items.length) { return items[0].toUpperCase(); } }

Slide 17

Slide 17 text

ⓒ atama plus Inc. 不要なコードを消してレビュー工数を削減できるルール その他のおすすめ no-unnecessary-boolean-literal-compare 不要なブール値とブールリテラルの比較をチェックできます。 たとえば以下の例では、someConditionがtrueであるかの比較は不要なので、 エラーや警告を出すことができます。 導入してみたいtypescript-eslintのルール 17 incorrect declare const someCondition: boolean; if (someCondition === true) { } correct declare const someCondition: boolean; if (someCondition) { }

Slide 18

Slide 18 text

踏みやすい落とし穴を回避して バグ発生を防止できるルール

Slide 19

Slide 19 text

ⓒ atama plus Inc. 踏みやすい落とし穴を回避してバグ発生を防止できるルール strict-boolean-expressions 以下のコードではnumが定義されているか(= undefinedではないか)どうかを if文で判定しています。 →num = 0のケースもfalsyなので、条件分岐の中に入らず 想定外の不具合を生んでしまいます。 導入してみたいtypescript-eslintのルール 19 declare const num: number | undefined; if (num) { console.log('num is defined'); }

Slide 20

Slide 20 text

ⓒ atama plus Inc. 踏みやすい落とし穴を回避してバグ発生を防止できるルール strict-boolean-expressions bool型が期待される式で非bool型の使用を禁止します。 今回の例では0という数値がfalsyな値として意図せず判定されてしまうことを 防ぐことができます。 導入してみたいtypescript-eslintのルール 20 incorrect declare const num: number | undefined; if (num) { console.log('num is defined'); } correct const num: number | undefined = 0; if (num != null) { console.log('num is defined'); }

Slide 21

Slide 21 text

ⓒ atama plus Inc. 踏みやすい落とし穴を回避してバグ発生を防止できるルール require-array-sort-compare 以下のコードではnumberの配列を引数なしでsortメソッドを 呼び出しています。 →引数なし(= ソート順を定義する関数がない)の場合は、 どんな型の要素でも文字列として認識されてソートされてしまいます。 導入してみたいtypescript-eslintのルール 21 const array: number[]; array.sort(); // [1, 2, 10, 3, 20].sort(); -> [1, 10, 2, 20, 3]

Slide 22

Slide 22 text

ⓒ atama plus Inc. 踏みやすい落とし穴を回避してバグ発生を防止できるルール require-array-sort-compare string型のArray以外で引数なしのsortメソッドの使用を禁止します。 今回の例では文字列の要素としてソートされて 意図しない順序になってしまうことを防ぐことができます。 導入してみたいtypescript-eslintのルール 22 incorrect const array: number[]; array.sort(); correct const array: number[]; array.sort((a, b) => a - b);

Slide 23

Slide 23 text

ⓒ atama plus Inc. 踏みやすい落とし穴を回避してバグ発生を防止できるルール その他のおすすめ restrict-plus-operands 型が異なる変数を+演算子で結合されるのを禁止できます。 導入してみたいtypescript-eslintのルール 23 const fn = (a: string, b: number) => a + b; // fn(“1”, 1); -> “11” restrict-template-expressions テンプレートリテラルにstring型以外の変数を埋め込むことを禁止できます。 const arg1 = { name: 'Foo' }; // `arg1 = ${arg1 || null}` -> 'arg1 = [object Object]'

Slide 24

Slide 24 text

モジュールの境界・依存関係を明確にして 治安を維持できるルール

Slide 25

Slide 25 text

ⓒ atama plus Inc. モジュールの境界・依存関係を明確にして治安を維持できるルール no-restricted-imports 以下のコードではdeprecatedされたモジュール(deprecated-foo)からimportさ れたり、ラッパーを用意してるにも関わらず直接外部ライブラリ(@bar- library)からimportが行われています。 →いつまで経ってもdeprecatedされたモジュールが呼び出され続けたり、用意さ れたラッパーが使われないという状況が発生してしまいます。 導入してみたいtypescript-eslintのルール 25 import foo from 'deprecated-foo'; import { bar } from '@bar-library';

Slide 26

Slide 26 text

ⓒ atama plus Inc. モジュールの境界・依存関係を明確にして治安を維持できるルール no-restricted-imports 指定されたモジュールのimportを禁止します。 今回の例ではdeprecatedされたモジュール(deprecated-foo)からのimportや ラッパーを用意してるにも関わらず外部ライブラリ(@bar-library)から 直接importをされてしまうことを防ぐことができます。 ※別途no-restricted-importsに関するeslintrcの設定が必要です。 導入してみたいtypescript-eslintのルール 26 incorrect import foo from 'deprecated-foo'; import { bar } from '@bar-library'; correct import foo from 'new-foo'; import { bar } from 'bar-lib-wrapper';

Slide 27

Slide 27 text

ⓒ atama plus Inc. モジュールの境界・依存関係を明確にして治安を維持できるルール その他のおすすめ explicit-module-boundary-types exportされた関数およびクラスのpublic classメソッドに明示的な戻り値と引 数の型を要求します。 導入してみたいtypescript-eslintのルール 27 incorrect export function test() { return; } export const arrowFn = () => 'test'; correct export function test(): void { return; } export const arrowFn = (): string => 'test';

Slide 28

Slide 28 text

ⓒ atama plus Inc. 以上です! みなさんおすすめのESLintプラグインやルールも ぜひ教えてください! 28

Slide 29

Slide 29 text

ともに “ Wow students. ”を届ける仲間を募集しています! 「atamaplus 採用」 @atamaplus_dev