TL;DR
- オブジェクトは、プロパティを後から足さずに一度に構築する。
- プロパティを追加したいときは、スプレッド構文を使えば型安全に追加できる。
内容
一度に構築すべき理由
オブジェクトを一度に構築すべき理由は 2 つある。1 つ目は、TypeScript では変数の値が変わっても、型は通常変わらないことである。
const pt = {}
pt.x = 3 // 型エラー
pt.y = 4 // 型エラー2 つ目は、宣言された型を持つ変数にオブジェクトリテラルを代入すると、余剰プロパティチェックが走ることである。
interface Point {
x: number
y: number
}
const pt: Point = {} // 型エラー
pt.x = 3
pt.y = 4型アサーションを使えば回避できるが、避けるべきである(項目9)。
スプレッド構文でプロパティを追加する
スプレッド構文を使うと、型安全にプロパティを追加できる。
const pt0 = {}
const pt1 = { ...pt0, x: 3 }
const pt2: Point = { ...pt1, y: 4 }スプレッド構文で {} や falsy な値(null、undefined、false)を展開しても、プロパティは追加されない。これを利用すると、条件を満たすときだけプロパティを追加できる。
declare let hasMiddle: boolean
const firstLast = { first: "Harry", last: "Truman" }
const president = { ...firstLast, ...(hasMiddle ? { middle: "S" } : {}) }
// president: { middle?: string; first: string; last: string }複数のプロパティをまとめて追加することもできる。
declare let hasDates: boolean
const nameTitle = { name: "Khufu", title: "Pharaoh" }
const pharaoh = { ...nameTitle, ...(hasDates && { start: -2589, end: -2566 }) }
// pharaoh: { start?: number; end?: number; name: string; title: string }既存のオブジェクトや配列を変換する場合
既存のオブジェクトや配列から新しいものを作る場合、「一度に構築する」に当たるのは、map や reduce といった関数型の API や、Lodash のようなユーティリティライブラリを使うことである(項目26)。