型弱おじさんが「Type Challenges」に入門した話

TypeScript は雰囲気で書いてるレベルで、複雑な型を読んだり書いたりするのは厳しい。そんな型弱おじさんな私が「[Type Challenges](https://github.com/type-challenges/type-challenges/blob/main/README.ja.md)」の初級をなんとか無事に終わらせることができた、この記事はそういう話です。


## チャレンジのきっかけ
型についてレビューで指摘されることが増え、「指摘内容もよくわからん！」という何とも言えない事態が幾度か続きました。

例えば

```TypeScript
export type Method =
  | 'method1'
  ...(省略)
  
export type Payload = {
  'method1': ...(省略)
  ...(省略)
}

export interface Data<T extends Method> {
  method: T
  payload: Payload[T]
}
```

Messaging API で渡される値を定義するジェネリクス型で、読み方が分からずに躓きました。
そもそもジェネリクス型を正しく理解できていなかったのだと、今であれば理解できます。

圧倒的経験不足。

しかし、TypeScript の書籍を読んでも型の理解は一向に身につかず、なにか実践的な形式で試せるものがないか、と辿り着いたのが「Type Challenges」でした。


## やったこと
一人でトライしても続かない可能性が高かったので、チームの有識者に相談し業務の一環として周りの人間を巻き込ませていただきました。
具体的にはチーム内で「Type Challenges」をやることを宣言し、毎週1時間の参加自由枠の予定を確保しました。

結果として、私も含め計4名が参加し、2023年11月から始めた「Type Challenges」は、無事6回目で初級の過程を修了できました。


## 成長の実感
恥ずかしながら、はじめのころは問題で問われていることすら理解できず、参加メンバーにサポートしてもらいなんとか理解できるレベルでした…。
しかし、5回目くらいには「前回の問題で出た infer を使えば書けそう」「これは分割代入するだけ良さそうだけど、他に方法はないか？」など、参加メンバーと会話しながら、問題で要求されていることや正解の型を予測することができるようになってきていたのです。

久々に自身が成長していると目に見えて実感することができた瞬間でした。


## これからやる人に向けて

### 初級…難易度高くない？
初級に書かれている順番通りに進めたのですが、難易度のギャップに驚きました。個人的な見解にはなりますが、下記のグループ順にチャレンジするのがオススメです。

1. ★☆☆☆☆: [If](https://github.com/type-challenges/type-challenges/blob/main/questions/00268-easy-if/README.ja.md)
1. ★☆☆☆☆: [Concat](https://github.com/type-challenges/type-challenges/blob/main/questions/00533-easy-concat/README.ja.md), [Push](https://github.com/type-challenges/type-challenges/blob/main/questions/03057-easy-push/README.ja.md), [Unshift](https://github.com/type-challenges/type-challenges/blob/main/questions/03060-easy-unshift/README.ja.md)
1. ★★☆☆☆: [Pick](https://github.com/type-challenges/type-challenges/blob/main/questions/00004-easy-pick/README.ja.md), [Readonly](https://github.com/type-challenges/type-challenges/blob/main/questions/00007-easy-readonly/README.ja.md)
1. ★★★☆☆: [Tuple of Object](https://github.com/type-challenges/type-challenges/blob/main/questions/00011-easy-tuple-to-object/README.ja.md), [Length of Tuple](https://github.com/type-challenges/type-challenges/blob/main/questions/00018-easy-tuple-length/README.ja.md), [First of Array](https://github.com/type-challenges/type-challenges/blob/main/questions/00014-easy-first/README.ja.md)
1. ★★★★☆: [Exclude](https://github.com/type-challenges/type-challenges/blob/main/questions/00043-easy-exclude/README.ja.md)
1. ★★★★★: [Parameters](https://github.com/type-challenges/type-challenges/blob/main/questions/03312-easy-parameters/README.ja.md)
1. ★★★★★★★★: [Includes](https://github.com/type-challenges/type-challenges/blob/main/questions/00898-easy-includes/README.ja.md), [Awaited](https://github.com/type-challenges/type-challenges/blob/main/questions/00189-easy-awaited/README.ja.md)


### 事前知識として
理解している人にとっては当然のことかもしれませんが、下記についての知識があると理解が早まるはずです。

- Generics
- keyof, typeof
- extends
- infer
- ユーティリティ型

私はどれも中途半端にしか理解していなかったり、そもそも知らなかったりで、とても苦労しました。


## 最後に
初級は終わりましたが「Type Challenges」にはまだまだ問題がたくさん用意されているので、今後もチャレンジを継続して、どこまでやれるか頑張りたいと思います。

もしこの記事を見て、興味を持たれた方やチャレンジしたことが無い方は、ぜひチャレンジして感想を聞かせてください。


## 参考文献
- [【TypeScript】typeof, keyof, in の挙動に関する備忘録
](https://qiita.com/y-kaanai/items/9f80e284b434787fe45f)
- [ナメやがってこの型ァ!!超イラつくぜぇ～～～～～ッ!!
](https://zenn.dev/yamadadayo123/articles/bf24f86d806528#extends)
- [【TypeScript】 inferに詳しくなろう
](https://qiita.com/ehika/items/8f41d4a3c8f9df4af9c3)
- [TypeScript: Promise風に振る舞うクラスの作り方
](https://qiita.com/suin/items/b9d00dff380486338ecd)
- [Interface Thenable<T>
](https://microsoft.github.io/PowerBI-JavaScript/interfaces/_node_modules__types_jquery_misc_d_.jquery.thenable.html)
- [TypeScriptのコンパイラを見てtype-challengesのEqual<X, Y>を完全に理解する
](https://zenn.dev/yumemi_inc/articles/ff981be751d26c)