ryokatsu.dev

【書評】プログラミングTypeScript 〜第4章〜


O’Reillyから発売されている「プログラミングTypeScript」の書評。

https://www.oreilly.co.jp/books/9784873119045/

4章 関数

以下を学んでいく

  • TypeScript での関数の宣言方法と呼び出し方法
  • シグネチャのオーバーロード
  • 関数についてのポリモーフィズム
  • 型エイリアスについてのポリモーフィズム

オプションパラメーターとデフォルトパラメーター

  • 関数本体は常に型推論されるが、パラメータについては型推論しないので明示的にアノテーションをつける。
  • 引数忘れや、引数の型が違うとエラーを出してくれる
  • ?を使うことでパラメーターの省略を宣言可能
  • デフォルトパラメータをつけることもできる
function log(message: string, userId = 'Not signed in') {
  let time = new Date().toISOString()
  console.log(time, message, userId)
}
log('User clicked on a button', 'da763be') log('User signed out')
  • デフォルトパラメーターに明示的な型アノテーションを加えることも可能
type Context = {
  appId?: string
  userId?: string
}

function log(message: string, context: Context = {}) {
  let time = new Date().toISOString()
  console.log(time, message, context.userId)
}

可変長引数の型宣言(レストパラメータ)

  • 可変長引数(arguments)は配列っぽいけど配列じゃないから一度配列に変換して呼び出さないといけない(JS)
  • そもそもargumentsは型が安全ではない。

以下がanyと推論されるケース

function sumVariadic(): number {
  return Array
  .from(arguments)
  .reduce((total, n) => total + n, 0)
}

以下のようにargumentsを使用しないで以下のレストパラメータを使用する。

function sumVariadicSafe(...numbers: number[]): number {
  return numbers.reduce((total, n) => total + n, 0)
}

this の型付け

thisのアノテーションは以下のようにする。


function fancyDate(this: Date) {
  return `${this.getMonth() + 1}/${this.getDate()}/${this.getFullYear()}`
}

fancyDate.call(new Date) // yyyy/mm//dd
fancyDate() // エラー

ジェネレーター、イテレータ

当然アノテーションできる

  • どこかでブログ書くので、今回は省略

呼び出しシグネチャ

  • 関数本体への型アノテーションFunction型は使わない。

以下のようにアロー関数のような記法でアノテーションする

type Log = (message: string, userId?: string) => void

let log: Log = (
  message,
  userId = 'Not signed in'
) => {
  let time = new Date().toISOString()
  console.log(time, message, userId) 
}
  1. Log型を型付けする。
  2. Logから型推論させる
  3. userIdにデフォルト値を追加
  4. 戻り値を再びアノテートする必要はない。
  • オーバーロードされた関数の型 複数の場所で呼び出されるシグネチャをもつ関数は完全なシグネチャで記述した方がよい
// 完全な呼び出しシグネチャ
type Log = {
  (message: string, userId?: string): void
}

ポリモーフィズム(ジェネリクス)

ジェネリクスは以下の記事がわかりやすいので省略

https://qiita.com/Yametaro/items/bcd3166e5d2ad696a89e

型駆動開発

  • 型シグネチャで概略を記述し、その後で値を埋め込むプログラミングのスタイルのこと
  • 今までは実装を先行して型がなんであるかを導いていたが、TypeScriptではまず型シグネチャから考えてその後に実装していくのが望ましい。