constアサーション「as const」 (const assertion)
オブジェクトリテラルの末尾にas const
を記述すればプロパティがreadonly
でリテラルタイプで指定した物と同等の扱いになります。
typescript
const pikachu = {name: "pikachu",no: 25,genre: "mouse pokémon",height: 0.4,weight: 6.0,} as const;
typescript
const pikachu = {name: "pikachu",no: 25,genre: "mouse pokémon",height: 0.4,weight: 6.0,} as const;
代入はもちろんできません。
typescript
pikachu.name = "raichu";// Cannot assign to 'name' because it is a read-only property.
typescript
pikachu.name = "raichu";// Cannot assign to 'name' because it is a read-only property.
readonly
とconst assertion
の違い#
どちらもオブジェクトのプロパティをreadonly
にする機能は同じですが、以下が異なります。
readonly
はプロパティごとにつけられる#
const assertion
はオブジェクト全体に対する宣言なので、すべてのプロパティが対象になりますが、readonly
は必要なプロパティのみにつけることができます。
const assertion
は再帰的にreadonly
にできる#
オブジェクトの中にオブジェクトがあるときの挙動が異なります。たとえば次のようなオブジェクトがあるとします。
typescript
type Country = {name: string;capitalCity: string;};type Continent = {readonly name: string;readonly canada: Country;readonly america: Country;readonly mexico: Country;};const america: Continent = {name: "North American Continent",canada: {name: "Republic of Canada",capitalCity: "Ottawa",},us: {name: "United States of America",capitalCity: "Washington, D.C.",},mexico: {name: "United Mexican States",capitalCity: "Mexico City",},};
typescript
type Country = {name: string;capitalCity: string;};type Continent = {readonly name: string;readonly canada: Country;readonly america: Country;readonly mexico: Country;};const america: Continent = {name: "North American Continent",canada: {name: "Republic of Canada",capitalCity: "Ottawa",},us: {name: "United States of America",capitalCity: "Washington, D.C.",},mexico: {name: "United Mexican States",capitalCity: "Mexico City",},};
ここでContinent
のタイプエイリアスがもつプロパティはすべてreadonly
です。よって次のようなことはできません。
typescript
america.name = "African Continent";// Cannot assign to 'name' because it is a read-only property.america.canada = {name: "Republic of Côte d'Ivoire",capitalCity: "Yamoussoukro",};// Cannot assign to 'canada' because it is a read-only property.
typescript
america.name = "African Continent";// Cannot assign to 'name' because it is a read-only property.america.canada = {name: "Republic of Côte d'Ivoire",capitalCity: "Yamoussoukro",};// Cannot assign to 'canada' because it is a read-only property.
しかしながら、次のようなことは問題なくできてしまいます。
typescript
america.canada.name = "Republic of Côte d'Ivoire";america.canada.capitalCity = "Yamoussoukro";
typescript
america.canada.name = "Republic of Côte d'Ivoire";america.canada.capitalCity = "Yamoussoukro";
これはreadonly
をつけたプロパティがオブジェクトである場合に、そのオブジェクトのプロパティまでreadonly
にはしないことに起因します。
const assertion
はすべてのプロパティを固定する#
as const
を付けます。
typescript
const america = {name: "North American Continent",canada: {name: "Republic of Canada",capitalCity: "Ottawa",},us: {name: "United States of America",capitalCity: "Washington, D.C.",},mexico: {name: "United Mexican States",capitalCity: "Mexico City",},} as const;
typescript
const america = {name: "North American Continent",canada: {name: "Republic of Canada",capitalCity: "Ottawa",},us: {name: "United States of America",capitalCity: "Washington, D.C.",},mexico: {name: "United Mexican States",capitalCity: "Mexico City",},} as const;
readonly
と同様にトップレベルのプロパティへの代入はできません。
typescript
america.name = "African Continent";// Cannot assign to 'name' because it is a read-only property.america.canada = {name: "Republic of Côte d'Ivoire",capitalCity: "Yamoussoukro",};// Cannot assign to 'canada' because it is a read-only property.
typescript
america.name = "African Continent";// Cannot assign to 'name' because it is a read-only property.america.canada = {name: "Republic of Côte d'Ivoire",capitalCity: "Yamoussoukro",};// Cannot assign to 'canada' because it is a read-only property.
これだけではなくオブジェクトが持つプロパティも同様にreadonly
にしてくれます。
typescript
america.canada.name = "Republic of Côte d'Ivoire";// Cannot assign to 'name' because it is a read-only property.america.canada.capitalCity = "Yamoussoukro";// Cannot assign to 'capitalCity' because it is a read-only property.
typescript
america.canada.name = "Republic of Côte d'Ivoire";// Cannot assign to 'name' because it is a read-only property.america.canada.capitalCity = "Yamoussoukro";// Cannot assign to 'capitalCity' because it is a read-only property.