最近ReactとTypeScriptを使っているので、こちらの本を読んだりコードを書いたりしました。
この本の対象者
対象者について、以下のように書かれていました。
- どのような言語であれ、ある程度プログラミングの経験がある人
- 関数、変数、クラス、エラーの基礎を理解している人
- JavaScriptで言えば、DOMやネットワークの基礎を知っている人
本書を読む前に知っておいた方がいいこと
- JavaScriptの基礎知識
1章 イントロダクション
なぜ型があると安全なのか、具体的な例を用いて触れていました。
3 + [] // 文字列の"3"と評価される let obj = {} obj.foo // undefinedと評価される
JavaScriptはこういった仕様のため、意図していない動作をしているのに気づくのが遅くなってしまいます。
TypeScriptだと、上のようなコードを書いても、型のエラーを出してくれるので実行する前や本番にデプロイする前にテキストエディタでエラーを教えてくれます。
2章 TypeScript:全体像
型チェッカー
TypeScriptのコンパイルについて。
TypeScriptとJavaScriptの型システムの違いについて
- 型がどのようにバインドされるか
- 型は自動的に変換されるか
- 型はいつチェックされるか
- エラーはいつ表面化するか
など、TSとJSの違いについて書かれていました。
エディタ
何使ってもいいけど、やっぱりVSCodeがおすすめみたい。
この辺りでTSのプロジェクトを作るのですが、npmだと遅すぎてなかなか始められなかったので
yarn install
yarn add --save-dev typescript tslint @types/node
でプロジェクトを作成しました。
./node_modules/.bin/tscでコンパイルできなかったので、npmでtscをインストールしてやりました。何か手順間違ってたかな...?😔
~/TS-study master* 2m 52s ❯ npm install -g tsc npm WARN deprecated tsc@1.20150623.0: you probably meant to install typescript /usr/local/bin/tsc -> /usr/local/lib/node_modules/tsc/bin/tsc /usr/local/bin/tsserver -> /usr/local/lib/node_modules/tsc/bin/tsserver + tsc@1.20150623.0 added 1 package from 1 contributor in 2.975s ~/Desktop/works/Study/TS-study master* 28s ❯ tsc src/index.ts --outDir dist/ ~/Desktop/works/Study/TS-study master* ❯ node ./dist/index.js Hello TypeScript
tsconfig.json
TypeScriptのプロジェクトに必ずあるファイル。オプションについて詳しく書かれていました。
最新の完全なリストはこちら
TypeScript: Documentation - tsc CLI Options
tslint.json
一貫したコーディングスタイルにするために用意するファイル。
でも、TypeScriptのプロジェクトを作ったらこんな警告が出てきました。
TSLintはESLintを採用して、廃止されちゃったみたいですね...。
TSLint has been deprecated in favor of ESLint.
3章 型について
型のメリットと、以下の型について詳しく。
書き方だけじゃなくて、注意点や役割も詳しく書かれていました。
- any
- unknown
- boolean
- number
- string
- オブジェクト
- 型エイリアス、合併、交差
- 配列
- タプル
- null, undefined, void, never
- 列挙型
4章 関数
- 関数の宣言方法
// 名前付き関数 function greet(name: string) { return 'hello' + name } // 関数式 let greet2 = function(name: string) { return 'hello' + name } // アロー関数式 let greet3 = (name: string) => { return 'hello' + name } // アロー関数式の省略記法 let greet4 = (name: string) => 'hello' + name
- オプションパラメーターとデフォルトパラメーター
?を使ってパラメーターを省略可能にできる。
必須のパラメーターを先に指定し、省略パラメーターをそのあとに指定する。
- レストパラメーター
可変長引数の関数を安全に型付けする。
- 呼び出しシグネチャ
アロー関数のような書き方でアノテーションをする
(a: number, b: number) => number
- 型レベルのコード、値レベルのコード
静的な型を持つプログラミングについて議論するときに使われる言葉。これらの用語について共通のボキャブラリーを持つと便利。
以下の記事がめっちゃわかりやすいです!!
4歳娘「パパ、具体的な名前をつけないで?」 - Qiita
例えば、stringだけの配列もnumberだけの配列もobjectだけの配列も受け取れるような関数を作りたいときに使えます。引数に型を書いて、関数の方は抽象的な型をつけるそうです。
function stringToArray<T>(str: T): T[] { return [str, str, str]; } const array = toArray<string>('あ'); const array = toArray<number>(3); const array = toArray<object>({hoge: 1});
- 型駆動開発
型シグネチャを見ただけで、関数の実装が直感的にわかる場合がある。
先に型で概略を記述し、後から詳細を始めるとTypeScritpの恩恵が受けられる。
5章 クラスとインターフェース
TypeScriptでは、C#から多くのものを借用しており、アクセス修飾子、プロパティ初期化子、ポリモーフィズム、デコレーター、インターフェースといったものをサポートしている。
(オブジェクト指向の用語がたっぷり出てきたので、Javaで復習した方が良さそうだと思いました。)
- クラスと継承
public, protected, privateがある。
abstractクラス(抽象クラス)もある。インスタンス化できない。
- super
子クラスが親クラスで定義されたメソッドをオーバーライドする場合に、子クラスのインスタンスはsuper呼び出しができる。
- インターフェース
typeとinterfaceは似ているけど、使い方が違う。
// Type type Food = { calories: number tasty: boolean } type Sushi = Food & { salty: boolean } type Cake = Food & { sweet: boolean } // interface interface Food { calories: number tasty: boolean } interface Sushi extends Food { salty: boolean } interface Cake extends Food { sweet: boolean }
ポリモーフィズムもTypeScriptでできる!
ポリモーフィズム:プログラマー1年生がポリモーフィズムについて学んだのでRPGで説明する。 - Qiita
- ミックスイン
- デコレーター
- デザインパターン
ファクトリーパターン、ビルダーパターンについて
6章 高度な型
型システムって、こんな考え方や機能があるんだ〜って勉強になりました。
「何かを表現する方法に苦労しているときにこの章に戻ってきてね」と書いてあったのでそうしようと思います。
- サブタイプ
AとBという2つの型があり、BがAのサブタイプ(派生型)である場合、Aが要求されるところではどこでもBを安全に使うことができる。例えば、配列はオブジェクトのサブタイプ。オブジェクトが要求されるところではどこでも配列も使うことができる。
1とnumber:リテラル型の1はnumberのサブタイプなので、numberに割り当て可能。
numberと1:numberはリテラル型の1のスーパータイプなので、1に割り当てることはできない。
- 割り当て可能性
割り当て可能とは、型Bが要求されているところで別の型Aを使用できるかどうか。
- 変性
ほとんどの型は、サブタイプが何か直感的に理解できる。しかし、パラメータ化された(ジェネリック型)や複雑な型については話が複雑になる。
不変性...Tそのものを必要とする
共変性...サブタイプか、Tそのもの
反変性...スーパータイプか、Tそのもの
双変性...サブタイプか、スーパータイプであればOK
TypeScriptは、使いやすさと安全性のバランスを取るために、オブジェクトの型を不変にしていないのでこのような性質がある。
- 型の拡大
TypeScriptの型推論がどのように機能するか理解するための鍵。
let a = 'x' // string const a = 'x' // 'x'
letやvarを使って宣言すると、その変数の型はリテラル値からそのリテラルが属するベースの型へと拡大する。
Bという型があり、AはBのスーパークラス、BはCのスーパークラスという関係の時、BはAまたはCであることを型チェッカーに主張することができる。これを型アサーションと呼ぶ。
7章 エラー処理
TypeScriptでよく使われるエラー表現&処理
以下4つの方法について、解説されていました。
- nullを返す
- 例外をスローする
- 例外を返す
- Option型
8章 非同期プログラミングと並行、並列処理
非同期処理
ネットワーク要求を行う、データベースやファイルシステムの入出力を扱う、ユーザーとの対話に応答する、CPU負荷の高い作業を別々のスレッドに振り分けるといったアプリケーションの基礎的要素は、コールバック、プロミス、ストリームなどの非同期APIを利用している。
コールバック
シンプルな非同期タスクで使う
プロミスとasync/await
複数のタスクを直列または並列に並べたい場合に使う
イベントエミッター
プロミスでうまくいかない非同期処理に使う。
JavaScriptでポピュラーなデザインパターン。
型安全なマルチスレッディング
CPU負荷の高いタスクなど、複数のスレッドに拡張するときはWeb Workerとか使う。
9章 フロントエンドとバックエンドのフレームワーク
クライアントとサーバーの両方でよくある問題を解決するためのポピュラーなツールとフレームワークの紹介。
- React
TSX = JSX + TypeScript
ReactとTypeScriptがどうして相性がいいのか、ReactにTypeScriptを用いると何が便利なのかよく分かりました。
- 型安全なAPI
RESTful APIのためのSwagger Codegen、GraphQLのためのApollo、RPCのためのgRPCなどのツールを使うと、APIに型安全性を追加できる。
(最近みんながよく話してる単語が出てきた...ここで繋がりました...)
- TypeORM
安全にデータベースと対話できる
11章 JavaScriptとの相互運用
TypeScriptを実践的な方法で記述することを学ぶ。
すでにあるJavaScriptプロジェクトに、TypeScriptを導入する具体的な方法が書かれていた。
12章 TypeScriptのビルドと実行
TypeScriptのアプリケーションを作成し、ブラウザー内またはサーバー上の本番環境で実行するために知っておく必要のあることが取り上げられていた。
コンパイルするJavaScriptのバージョンの選び方、使用する環境でどのライブラリを利用するか、コンパイル時間を短くするためのTypeScriptプロジェクトのモジュール化など。
(ナンモ・ワカラン=コンド・ヨム)
TypeScriptのコードをnpmに公開する方法もありました。
まとめ
TypeScriptがどのようにコンパイルされるのか〜TypeScriptのコードをnpmに公開するまで幅広く書かれていました。
理解できないところもありましたが、コードを書きつつわからないことがあったら本書に立ち帰ろうと思います。
取り急ぎTypeScriptで使われる用語のインデックスを増やすことができたので満足です!TypeScriptを書く人は手元に置いておくべき1冊ですね!