0Pricing
TypeScript Academy · レッスン

readonlyプロパティ

初期化後に変更できないよう、オブジェクトのプロパティをreadonlyとして指定します。

「readonlyプロパティ」はCoddyKit上の無料TypeScript Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはTypeScript Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 TypeScript Academyコースには全4レッスンが含まれています。

readonly修飾子

readonly修飾子は、プロパティを一度だけ設定でき、その後は再代入できないことを示します。型レベルで不変性を表現し、意図しない変更を防ぎます。

interface Point {
  readonly x: number;
  readonly y: number;
}
const p: Point = { x: 1, y: 2 };
console.log(p.x, p.y);
// p.x = 5; // Error: cannot assign to readonly property

インターフェイスでのreadonly

インターフェイスでは、readonlyによって作成後に固定されるフィールドを明示できます。利用側は自由に読み取れますが、コンパイラーは再代入を禁止します。

interface Config {
  readonly env: string;
  retries: number; // mutable
}
const c: Config = { env: 'prod', retries: 3 };
c.retries = 5; // allowed
console.log(c.env, c.retries);

再代入時のコンパイルエラー

readonlyプロパティに値を書き込もうとすると、コンパイル時エラーになります。これにより、共有状態が予期せず変更される種類のバグをまとめて検出できます。

interface User {
  readonly id: number;
  name: string;
}
const u: User = { id: 1, name: 'Ada' };
u.name = 'Grace'; // ok
// u.id = 2; // Error
console.log(u);

クラスプロパティでのreadonly

クラスでもreadonlyを使用できます。readonlyフィールドは宣言時またはコンストラクター内で初期化できますが、それ以外の場所では初期化できません。

class Circle {
  readonly radius: number;
  constructor(r: number) {
    this.radius = r; // allowed in constructor
  }
}
const c = new Circle(5);
console.log(c.radius);

コンストラクターで一度だけ設定する

宣言以外でreadonlyフィールドに代入できるのは、コンストラクターだけです。構築が完了すると、その値はオブジェクトの存続期間中固定されます。

class Account {
  readonly owner: string;
  constructor(owner: string) {
    this.owner = owner;
  }
  rename() {
    // this.owner = 'x'; // Error: readonly outside constructor
  }
}
console.log(new Account('Sam').owner);

readonlyパラメータープロパティ

TypeScriptのパラメータープロパティを使うと、コンストラクターのシグネチャ内でreadonlyフィールドの宣言と初期化を直接行えるため、定型コードを減らせます。

class Vector {
  constructor(
    readonly x: number,
    readonly y: number
  ) {}
}
const v = new Vector(3, 4);
console.log(v.x, v.y);

readonlyはコンパイル時のみ

重要なのは、readonlyが型システムにのみ存在する点です。実行時には消去され、JavaScriptにはこの概念がありません。TypeScriptコード内での再代入は防ぎますが、型付けされていない経路を通じてコンパイル後の出力に到達した場合の再代入までは防ぎません。

interface Box { readonly value: number; }
const b: Box = { value: 10 };
// At runtime b is a plain object; readonly is not enforced by JS.
console.log(b.value);

readonlyとconstの違い

この2つを混同しないでください。constは変数の再束縛を防ぎます。readonlyはプロパティへの再代入を防ぎます。constオブジェクトでも、そのプロパティがreadonlyでなければ変更できます。

const obj = { count: 0 }; // const binding
obj.count = 5; // allowed: property is mutable
console.log(obj.count);

本質的に浅い保護

readonlyは浅い保護です。プロパティ自体は保護しますが、そのプロパティが参照するオブジェクトや配列の内容までは保護しません。オブジェクトへのreadonly参照があっても、そのオブジェクトのフィールドは変更できます。

interface Holder { readonly data: { n: number }; }
const h: Holder = { data: { n: 1 } };
// h.data = {...}; // Error
h.data.n = 99; // allowed: inner field is not readonly
console.log(h.data.n);

より安全なAPIのためのreadonly

返されるオブジェクトのフィールドにreadonlyを付けると、呼び出し側がそれらを変更すべきでないことを示せます。意図を型に組み込むことで、誤用を気付かれにくいバグではなくコンパイルエラーにできます。

interface Snapshot { readonly takenAt: number; readonly size: number; }
function snapshot(): Snapshot {
  return { takenAt: Date.now(), size: 1024 };
}
const s = snapshot();
console.log(s.size);

インデックスシグネチャでのreadonly

インデックスシグネチャもreadonlyにできます。これにより、インデックス経由ではエントリを読み取れても再代入はできない、マップのような型を作れます。

interface Scores {
  readonly [name: string]: number;
}
const scores: Scores = { ada: 95, sam: 88 };
console.log(scores.ada);
// scores.ada = 100; // Error

クイックチェック

readonlyプロパティについての理解度を確認しましょう。

まとめ:readonlyプロパティ

readonlyについて、次のことを学びました。

  • プロパティを一度だけ設定でき、その後の再代入を禁止します。
  • クラスフィールドでは、宣言時またはコンストラクター内で設定できます。
  • コンパイル時のみ、かつ浅い保護です。ネストされたデータを深く凍結することはありません。
  • constとは異なります。一方はプロパティを保護し、もう一方は変数の束縛を保護します。

次は、readonly配列とタプルです。

interface Meta { readonly id: number; }
const m: Meta = { id: 42 };
console.log(m.id);

よくある質問

「readonlyプロパティ」レッスンは無料ですか?

はい。「readonlyプロパティ」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、TypeScript Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 TypeScript Academyコースには全4レッスンが含まれています。

「readonlyプロパティ」で何を学びますか?

初期化後に変更できないよう、オブジェクトのプロパティをreadonlyとして指定します。 ブラウザで直接実行するハンズオンコードでTypeScript Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

TypeScript Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのTypeScript Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「readonlyプロパティ」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このTypeScript Academyレッスンでコードを書いて実行できますか?

はい。すべてのTypeScript Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. readonlyプロパティ
  2. readonly配列とタプル
  3. ReadonlyArrayとReadonlyMap
  4. 深い不変性のパターン
← TypeScript Academyに戻る