readonly

書き換えてはいけない項目がある

Workid は、その作品を見分けるための番号です。タイトルは後から直してよくても、id が変わると別の作品になってしまいます。

けれど型の上では、titleid も同じ扱いです。

interface Work { id: number; title: string; published: boolean; } const work: Work = { id: 1, title: "プロフィールサイト", published: true }; work.id = 99; // 通ってしまう

プロパティ名の前に readonly を付けると、代入だけを止められます。

interface Work { readonly id: number; title: string; published: boolean; } work.id = 99; // エラー Cannot assign to 'id' because it is a read-only property. work.title = "プロフィールサイト v2"; // これは通る

作るときは普通に書ける

readonly が禁止するのは、できあがった後の代入だけです。オブジェクトを組み立てるときは今までどおり値を書けます。

const copy: Work = { id: work.id, title: "自己紹介カード", published: false };

だから readonly を付けた型を扱うときの基本は、書き換えるのではなく新しいオブジェクトを作って返す、という形になります。

function renameWork(work: Work, newTitle: string): Work { return { id: work.id, title: newTitle, published: work.published }; }

元のオブジェクトには触っていないので、呼び出した側の手元のデータが知らないうちに変わることもありません。React では、この「作り直して返す」書き方がそのまま state 更新のやり方になります。

効くのは検査のときだけ

readonly は TypeScript の検査のための印です。コンパイル後の JavaScript には残らないので、実行時に代入を止める力はありません。あくまで、書いている最中に間違いを見つけるための道具です。

手を動かす

演習では idreadonly にして、タイトルだけを差し替えた新しい作品を返す関数を書きます。

要件

  1. Workidreadonly にする
  2. 引数のオブジェクトを書き換えない
  3. idpublished は元の値のまま、title だけを差し替えた新しいオブジェクトを返す

入出力例

renameWork({"id":1,"published":true,"title":"プロフィールサイト"}, "プロフィールサイト v2"){"id":1,"published":true,"title":"プロフィールサイト v2"} renameWork({"id":2,"published":false,"title":"自己紹介カード"}, "自己紹介カード 改"){"id":2,"published":false,"title":"自己紹介カード 改"} renameWork({"id":42,"published":true,"title":"スキル一覧の表"}, "スキル表"){"id":42,"published":true,"title":"スキル表"}

ヒント

生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア
編集 LuaGate編集部
main.ts
main.ts
学習モード

メモ

readonly

⌘S で保存