Open5

「プログラミング TypeScript」 4章メモ

korallekoralle

【重要】
TypeScriptは関数において、多くの場合戻り値の型のみを推論する。
文脈から推論してくれる場合のみパラメータも推論してくれるが、基本的には明示的なアノテートが必要。

// const add1: (a: any, b: any) => any
// Parameter 'a' implicitly has an 'any' type.(7006)
const add1 = (a, b) => a + b

// const add2: (a: number, b: number) => number
// 戻り値の型は推論できるので明示しなくてもOK
const add2 = (a: number, b: number) => a + b
korallekoralle

可変長引数を表現する場合、JavaScriptのargumentsは危険。
TypeScriptはこのargumentsに割り当てられた引数を全てany型と推論してしまうからである。

そのため、TypeScriptではargumentsの代わりにレストパラメータが好まれる。

korallekoralle

事前に関数の呼び出しシグネチャを型エイリアスで定義しておくと、その呼び出しシグネチャと形状が一致することを明示された関数を定義する際にパラメータの型アノテートを省略することができる。

これは、TypeScriptの文脈的型付けと呼ばれる型推論機能である。

// 呼び出しシグネチャを型エイリアスとして事前定義する
type AddFunc = (a: number, b: number) => number

// パラメータの型アノテートが省略できる
const add3: AddFunc = (a, b) => a + b
korallekoralle

呼び出しシグネチャの記述形式は2通りある。

// こっちが正式
type AddFunc = {
  (a: number, b: number): number
}

// 上の省略形
type AddFunc = (a: number, b: number) => number
korallekoralle

使える時にはジェネリクスを使う。もはや最初からジェネリクス前提で書きたい。

type Profile = { name: string, age: number }
type Human = Profile & { weight: number, height: number }

const printProfile = <T extends Profile>(profile: T) => console.log(profile.name)

const koralle = { name: "koralle", age: 3 }
const hogehoge = { name: "hogehoge", age: 30, weight: 170, height: 65 }

// 変数koralleはProfile型であることを明示していないが、
// オブジェクトの形状がProfileに一致するのでコンパイルが通る。
printProfile(koralle) // "koralle"

// 変数koralleはProfile型であることを明示していないが、
// オブジェクトの形状がprintProfileの引数profileの条件を満たすのでコンパイルが通る。
printProfile(hogehoge) // "hogehoge"