「プログラミングTypeScript」読んだメモ
4章 関数
apply, call, bindの違い
thisを関数パラメータで型付けできる
関数のオーバーロード
関数はオブジェクトみたいなもの
ジェネリクスのスコープで推論を効率的に使えるかが変わる
レストパラメータにジェネリックを置く場合、そのジェネリックは配列を継承していないといけない
5章 クラスとインターフェイス
親クラスのメソッドの返り値にthisを使うと小クラスはオーバーライドせずに済むので便利
型とインターフェイスの違い
- typeは汎用的に右辺を置け(&や|)を使えるがインターフェイスは形状でなければならない
- 拡張時に拡張元のインターフェイスが拡張先のインターフェイスに割り当て可能かを確認する
- 宣言のマージ
インターフェイスは同じ名前でも分けて宣言可能。プロパティはマージされる。同じ名前だとエラーになる
インターフェイスのプロパティはreadonly指定可能
インターフェイスは汎用的かつ軽量。抽象クラスは目的に特化していて機能が豊富
インターフェイスは形状をモデル化し、コンパイル時のみ存在する
抽象クラスがモデル化できるのはクラスだけ、ランタイムコードを発行する。コンストラクタが持てて、デフォルト実装可能。プロパティやメソッドにアクセス修飾子がつけれる
複数のクラス間での実装を共有する場合は抽象クラス、「このクラスはTである」と表現するための軽量な方法が必要ならインターフェイスを使う
クラスは構造的に型づけされる
クラス名が違っても構造が同じであれば割当が可能
クラスはインスタンス型とコンストラクタ型で型が生成される。
typeof でコンストラクタ型を意味する
インスタンス型は、初期化後のメソッドやプロパティを持つ形のインターフェイスであり、コンストラクタ型はnewなどを持つインターフェイスになる
ミックスインは、is-aではなく、canやhas-aを表す
debug可能なクラスを生成するミックスインが実装可能。実装複雑だがかなり便利そう
6章 高度な型
ある形状が期待される場合、「プロパティの型<:期待される型」となるプロパティを持つ型は渡すことができる。これをTypescriptでは形状はそれらのプロパティに対して共変である
変性の話
不変、共変、半変、双変
関数のパラメータに他の関数を割り当てる際に、返り値については、受け渡す側は受け取り側の型に対して、サブタイプでなければならない。
また、パラメータについては、受け渡す側は受け取り側の型に対してスーパータイプでなければならない
一度constで定義し型を推論させた変数は、別の変数にletで割り当てると範囲が広がる。明示的に型アノテーションすると拡大を防げる
また、 as const
キーワードをつけると再帰的にreadonly にしてくれ、型の拡大を防いでくれる
過剰プロパティチェックというのがある
オブジェクトリテラルが変数に割り当てられたりしていない状態の場合は、フレッシュなオブジェクトになり、この場合には過剰プロパティチェックが行われる
合併型を使う場合、タグとなるプロパティを用意してその中で一意となる値をセットしてそれをもとに型の絞り込みを行うと良い
ルックアップ型
配列の要素の型にアクセスするときはこう書く
type Friend = FriendList['friends'][number]
MagicKeyboardで入力中