型のサブタイプとスーパータイプ
- サブタイプとは、派生型のこと。サブタイプから見た派生元をスーパークラスと言う
- オブジェクト指向言語では、一般的には継承によって表現される
上記において、ChatServiceがスーパータイプ、ApiChatService / WebSocketChatService がサブタイプになる
- 一般的に、サブタイプはスーパータイプに割当が可能である
- これを型の共変性という。
型の共変性を活用した設計
- 前回話したデザインパターンの多くは、この型の共変性を活かした設計をしている
- スーパータイプを利用するようにしておくことで、型の共変性により任意のサブタイプを実際には代入されてもよくなる
- 機能追加によるコードの変更範囲を絞ることができる
上記例で言えば、仮にChatサービスの実装方法がWebSocketからAPIに変わったとしても、上位のクラスへの影響がない、という状態にできる。
型の反変性
- 反変性とは、共変性の反対の性質、すなわち サブタイプにスーパータイプが割り当て可能な場合をいう
- 代表的なものとして、 関数オブジェクトにおけるメソッドの引数 がある。
type ElementClickEvent = ElementEvent & {
position: {x: number, y:number}
}
type ButtonClickEventHandler = (e: ElementClickEvent) => void
let handler: ButtonClickEventHandler
handler = (e: ElementEvent) => {console.log(e.message)} //反変性
type ElementMultiClickEvent = ElementClickEvent & {
clickCount: number
}
handler = (e: ElementMultiClickEvent) => {} //共変性をサポートしない