まんじ

フリーランスなウェブエンジニアをしてますう。25歳の頃にプログラミングを始めて27歳からフリーランスエンジニアになって生きてます

入門時にTypeScriptが難しい場合の解決策を列挙!

  • 2024/04/14
  • 2024/07/11
  1. プログラミング入門
入門時にTypeScriptが難しい場合の解決策を列挙!

始めに

こんにちは、まんじです!

今回は「TypeScript難しくね?」と思ってるおそらくTypeScript入門してる人に向けての対策をご紹介します。

TypeScriptに苦戦する人は「型」のあたりがおそらく意味不明なのかなと思うので、そこらへんをメインに書きたいと思います。

結論から書くと、TypeScriptの難しいっぽい部分は以下の解決策で大体解決できます。

  • TypeScript特有or頻出の分からない構文は落ち着いて調べてみる(AIにも聞く)
  • ジェネリクス(TとかPとか)は後回しにする
  • 型がどうしても合わない場合はasを使う
  • 型が難しすぎる場合はとりあえずanyで一旦逃げる
  • 複雑な型は頭の中だけで考えずにVS Codeに書き出して確認する
  • TypeScript入門時にざーっと読むとよいもの(対策というか紹介)

ぶっちゃけ最初はノリでany使いまくってればなんとかなる🙄のと、型を勉強しまくってできるようになるというよりかは、実装しながら型を合わせてると一般的な型は勝手に使えるようになります。

ジェネリクス(型変数、Tとか置くことが多い)も慣れてくると徐々に使えるようにはなるんですけど、そもそも複雑なジェネリクスを書くことは普通のウェブ開発とかの仕事ではほぼないかなーという感じです。(ライブラリ作るとかの場合はあるのかも。)

あと、型じゃなくてTypeScirptの文法が意味不明な場合(コールバック関数とはなんぞや、、、みたいな)は、JavaScriptの問題なのでJavaScriptの文法を見直すというか調べたりAIに聞くのが重要です。

ということで、TypeScriptの型が難しいって側面にフォーカスして書いてみます。

TypeScript特有or頻出の分からない構文は落ち着いて調べてみる

TypeScriptだとこういう文法が増えます。

const blogIds = req.params.blogIds ?? [];
const blogIdsNum = req.body?.blogIds ?? [];
type IButton = {
  onClick: () => void;
  onBlur: () => Promise<void>;
  headline?: string;
  option: number | null
}

といった感じで、undefinedをうまく扱う文法の ? ←クエッションマークみたいなのが増えるんですけど、これが入門の時に難しいように見えます。多分。

ちなみにクエッションマークはオプショナルチェーンとか言った気がしますけど、用語とかはあんまり覚えなくてOKです。

あとはkey valueのオブジェクトとかでしょうか。

const obj = {name: string, age: number, cry: () => void}

string[]とかnumber[]とかのプリミティブ型と配列らへんの型は直感的に分かると思います。

こういった(?とか)TypeScript特有の文法というか表現に関しては、とりあえず落ち着いて1つ1つ調べるのが大事です。

ChatGPTにつっこむのもいいですし、Googleに聞いてみるのも良いと思います。

聞く時は翻訳使って良いので英語のが将来的に楽です。

とりあえず分からない文法とか表現はChatGPTかGoogleに聞いてあげて、1個1個理解していくのが最初は大切です。

2~3ヶ月ぐらい書いていれば、徐々に調べる回数も減ってきますし、さらに書いていればそういった基本的なことは調べる必要がなくなります。

ジェネリクス(TとかPとか)は後回しにする

TypeScriptの型で難しいのがジェネリクスと言われる構文です。

型変数とも言われます。

function hello<T>(arg: T): T {
  console.log(arg);
  return arg;
}

上の例ならargがTという型変数(numberでもstringでもnullでもなんでもOK)を許容します。

この例だとジェネリクスの意味はほぼないんですけど、ライブラリと絡んでジェネリクスを使う必要に迫られた時が一般的に「つらい」と言われる状態になってかなり複雑でスパゲッティコードになりがちです。

結構難しくて、特に型をextendsしたり条件分岐させると脳が終わるので、最初の頃は脳死で出現するジェネリクスだけを扱ってあげれば良いと思います。

Promise<string[]>とかuseState<string>みたいな<>の中身に入るのが一応ジェネリクスなんですけど、使う時は基本的はあんまり何も考えずとも直感的に使えます。

型がどうしても合わない場合はasを使う

ライブラリを使っていたり型が不明なものを扱う時(APIのparamsとかbodyとか)に型が合わないことが多々あります。

stringの型を期待しているけれど、変な型のUnion3つとかがでてきちゃう場合とかです。(上の画像参照)

そういう時はとりあえずasで型を強制してあげるで良いカナーと思います。

ただ、type guardと言われる型のバリデーションを行う関数があるとより安全に型を扱えます。

type guardはこういう関数です。

const isString = (target: unknown): target is string => {
  return typeof target === "string"
}

「target is string」みたく書くのがtype guardの関数特有の表現です。

なんにせよ、型が合わない時は脳死では微妙ですけど、問題なさそうならとりあえずasで書いてあげてコメントとかも書いてあげると良いと思われます。

型が難しすぎる場合はとりあえずanyで一旦逃げる

TypeScript入門の頃は型が難しすぎる場合がたまにあります。

特にライブラリが絡んだ型は入門の頃は難しすぎる場合なケースが多いので、そう言う時にはanyを使いましょう。

基本的にanyはあんまり使わないほうがいいとされていますが、、、。

というのも、any使っちゃうとTypeScriptの型の良さが消えるからです。

ただ、どうしても型が合わない時とかはあるし、特に入門の頃は型になれていないことも多いと思うのでそう言う時にanyを使うのはかなり有効な手段となります。

でも基本的には使わないほうがいいというか、anyを実務で使うは理由がないとレビュアーにキレられます。

複雑な型は頭の中だけで考えずにVS Codeに書き出して確認する

上の画像のようにいわゆるネストしてる型とかのやや複雑な型は最初の頃は難しく感じます。

実務だと20~30個のフィールドがあってネストしていたりすることもあるので、そういう意味不明すぎる複雑な型とかはそいつを一旦別の場所に移動して1個1個ゆっくり見ていくのが便利です。

頭の中だけで処理すると脳が終わるので、なんというか書き出すことで、脳のメモリ消費量を抑えるみたいなイメージ。

TypeScript入門時にざーっと読むとよいもの

サバイバルTypeScript

https://typescriptbook.jp/

サバイバルTypeScriptはぼくもTypeScriptに入門してた頃に移動中とかにざーっと読んでいた記憶があります。

正直全部は覚えられないですし覚えようとしたところで意味がないのでおすすめしませんが、TypeScriptの入門時にはすごく有益なリソースです。

ただ、実際に書く方がTypeScript力は伸びるので、書きつつたまに暇な時とか移動中に読む程度に使うのが良いと思います。

ノートとかに書いちゃうのは微妙な勉強法です。とりあえず読んでおく程度でOK。

まとめ

いろいろ書いたんですけど、TypeScriptが難しいと感じるのは型の部分です。

もし普通にCallback関数とかPromiseが分からない場合にはJavaScriptの文法側の問題なのでそこは適宜調べつつって感じで良いと思います。

TypeScriptはJavaScriptから切り替えると最初難しく感じがちですが、慣れてくるとTypeScriptのほうが型が補完されて圧倒的に楽になってきます。

あとは最近の実務?仕事?開発?だと、JavaScriptじゃなくてTypeScriptを使うケースが99%ぐらいなので、なんにせよTypeScriptを頑張るといいかもしれません!

バックエンドもフロントエンドも書けるし!

TypeScript好きって人は多いですし、フリーランスとかで案件探す時も重宝するというか案件が多いです。

正社員で仕事する場合でもフリーランスで仕事をする場合でも、プログラミング言語はぶっちゃけTypeScriptで基本的には全てOK感は強めです。

(最終的に言語はそこまで関係なくなります。)

まんじ

フリーランスなウェブエンジニアをしてますう。25歳の頃にプログラミングを始めて27歳からフリーランスエンジニアになって生きてます