メインコンテンツまでスキップ

readonlyとconstの違い

JavaScriptでは、constで宣言した変数は代入不可になります。TypeScriptではオブジェクトの型のプロパティにreadonly修飾子をつけると、そのプロパティが代入不可になります。これら2つの機能は「代入不可」という点では似ています。ではこれらの違いは何でしょうか。

constは変数への代入を禁止にするもの

constは変数への代入を禁止するものです。たとえば、constで宣言されたxに値を代入しようとすると、TypeScriptではコンパイルエラーになり、JavaScriptでは実行時エラーになります。

ts
const x = 1;
x = 2;
Cannot assign to 'x' because it is a constant.2588Cannot assign to 'x' because it is a constant.
ts
const x = 1;
x = 2;
Cannot assign to 'x' because it is a constant.2588Cannot assign to 'x' because it is a constant.

constの代入禁止が効くのは変数そのものへの代入だけです。変数がオブジェクトだった場合、プロパティへの代入は許可されます。

ts
const x = { y: 1 };
x = { y: 2 }; // 変数そのものへの代入は不可
Cannot assign to 'x' because it is a constant.2588Cannot assign to 'x' because it is a constant.
x.y = 2; // プロパティへの代入は許可
ts
const x = { y: 1 };
x = { y: 2 }; // 変数そのものへの代入は不可
Cannot assign to 'x' because it is a constant.2588Cannot assign to 'x' because it is a constant.
x.y = 2; // プロパティへの代入は許可

readonlyはプロパティへの代入を禁止にするもの

TypeScriptのreadonlyはプロパティへの代入を禁止するものです。たとえば、readonlyがついたプロパティxに値を代入しようとすると、コンパイルエラーになります。

ts
let obj: { readonly x: number } = { x: 1 };
obj.x = 2;
Cannot assign to 'x' because it is a read-only property.2540Cannot assign to 'x' because it is a read-only property.
ts
let obj: { readonly x: number } = { x: 1 };
obj.x = 2;
Cannot assign to 'x' because it is a read-only property.2540Cannot assign to 'x' because it is a read-only property.

一方、変数自体への代入は許可されます。

ts
let obj: { readonly x: number } = { x: 1 };
obj = { x: 2 }; // 許可される
ts
let obj: { readonly x: number } = { x: 1 };
obj = { x: 2 }; // 許可される

constとreadonlyの違い

constは変数自体を代入不可するものです。変数がオブジェクトの場合、プロパティへの代入は許可されます。一方、readonlyはプロパティを代入不可にするものです。変数自体を置き換えるような代入は許可されます。以上の違いがあるため、constreadonlyを組み合わせると、変数自体とオブジェクトのプロパティの両方を変更不能なオブジェクトを作ることができます。

ts
const obj: { readonly x: number } = { x: 1 };
obj = { x: 2 };
Cannot assign to 'obj' because it is a constant.2588Cannot assign to 'obj' because it is a constant.
obj.x = 2;
Cannot assign to 'x' because it is a read-only property.2540Cannot assign to 'x' because it is a read-only property.
ts
const obj: { readonly x: number } = { x: 1 };
obj = { x: 2 };
Cannot assign to 'obj' because it is a constant.2588Cannot assign to 'obj' because it is a constant.
obj.x = 2;
Cannot assign to 'x' because it is a read-only property.2540Cannot assign to 'x' because it is a read-only property.

関連情報

📄️ 変数宣言: letとconst

JavaScriptの変数宣言(variable declaration)には、letとconstがあります。