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

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.

readonlyconst 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.

関連情報#