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