宮水の日記

宮水の日記

主に書評や資格取得について記事を書いています。

「プログラミング TypeScript」を読みました

最近ReactとTypeScriptを使っているので、こちらの本を読んだりコードを書いたりしました。


この本の対象者

対象者について、以下のように書かれていました。

  • どのような言語であれ、ある程度プログラミングの経験がある人
  • 関数、変数、クラス、エラーの基礎を理解している人
  • JavaScriptで言えば、DOMやネットワークの基礎を知っている人

本書でできること

以下のように書かれていました。

  • TypeScript言語がどのように動作するのか深く理解できる
  • 本番のTypeScriptの書き方について多くの実用的なアドバイスが読める

本書を読む前に知っておいた方がいいこと

1章 イントロダクション

なぜ型があると安全なのか、具体的な例を用いて触れていました。

 3 + [] // 文字列の"3"と評価される

let obj = {}
obj.foo  // undefinedと評価される

JavaScriptはこういった仕様のため、意図していない動作をしているのに気づくのが遅くなってしまいます。
TypeScriptだと、上のようなコードを書いても、型のエラーを出してくれるので実行する前や本番にデプロイする前にテキストエディタでエラーを教えてくれます。

2章 TypeScript:全体像

型チェッカー

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

コンパイルしたファイルがdistディレクトリに入って、無事実行できたことを確認しました ✌︎('ω')✌︎

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

安全にデータベースと対話できる

10章 名前空間とモジュール

  • JavaScriptモジュールの簡単な歴史
  • 動的インポート

 遅延読み込みやファイル分割の概念

  • importとexport
  • 名前空間(ただし、名前空間よりimportやexportを使う方が望ましい)
  • TypeScriptが行う3種類のマージがどのように動作するか

11章 JavaScriptとの相互運用

TypeScriptを実践的な方法で記述することを学ぶ。
すでにあるJavaScriptプロジェクトに、TypeScriptを導入する具体的な方法が書かれていた。

12章 TypeScriptのビルドと実行

TypeScriptのアプリケーションを作成し、ブラウザー内またはサーバー上の本番環境で実行するために知っておく必要のあることが取り上げられていた。
コンパイルするJavaScriptのバージョンの選び方、使用する環境でどのライブラリを利用するか、コンパイル時間を短くするためのTypeScriptプロジェクトのモジュール化など。
(ナンモ・ワカラン=コンド・ヨム)

TypeScriptのコードをnpmに公開する方法もありました。

まとめ

TypeScriptがどのようにコンパイルされるのか〜TypeScriptのコードをnpmに公開するまで幅広く書かれていました。

理解できないところもありましたが、コードを書きつつわからないことがあったら本書に立ち帰ろうと思います。

取り急ぎTypeScriptで使われる用語のインデックスを増やすことができたので満足です!TypeScriptを書く人は手元に置いておくべき1冊ですね!

次は、こちらのUdemyりあクト!をもう一周してさらに理解を深めていこうと思います!