Nhảy tới nội dung

Const assertion "as const"

Khi khai báo biến, thêm as const vào cuối sẽ làm cho giá trị đó thành readonly và chuyển thành literal type.
Với giá trị primitive type thì không cảm nhận được nhiều lợi ích, nhưng với array hoặc object literal thì rất tiện lợi.

ts
const str1 = "hello";
const str1: "hello"
const str2 = "hello" as const; // Trường hợp này có hay không as const cũng giống nhau
const str2: "hello"
const array1 = [1, 2, 3];
const array1: number[]
const array2 = [1, 2, 3] as const;
const array2: readonly [1, 2, 3]
const obj1 = {
const obj1: { name: string; no: number; genre: string; height: number; weight: number; }
name: "pikachu",
no: 25,
genre: "mouse pokémon",
height: 0.4,
weight: 6.0,
};
const obj2 = {
const obj2: { readonly name: "pikachu"; readonly no: 25; readonly genre: "mouse pokémon"; readonly height: 0.4; readonly weight: 6; }
name: "pikachu",
no: 25,
genre: "mouse pokémon",
height: 0.4,
weight: 6.0,
} as const;
ts
const str1 = "hello";
const str1: "hello"
const str2 = "hello" as const; // Trường hợp này có hay không as const cũng giống nhau
const str2: "hello"
const array1 = [1, 2, 3];
const array1: number[]
const array2 = [1, 2, 3] as const;
const array2: readonly [1, 2, 3]
const obj1 = {
const obj1: { name: string; no: number; genre: string; height: number; weight: number; }
name: "pikachu",
no: 25,
genre: "mouse pokémon",
height: 0.4,
weight: 6.0,
};
const obj2 = {
const obj2: { readonly name: "pikachu"; readonly no: 25; readonly genre: "mouse pokémon"; readonly height: 0.4; readonly weight: 6; }
name: "pikachu",
no: 25,
genre: "mouse pokémon",
height: 0.4,
weight: 6.0,
} as const;

Vì trở thành readonly nên đương nhiên không thể gán giá trị mới.

ts
array1[0] = 4;
array2[0] = 4;
Cannot assign to '0' because it is a read-only property.2540Cannot assign to '0' because it is a read-only property.
obj1.name = "raichu";
obj2.name = "raichu";
Cannot assign to 'name' because it is a read-only property.2540Cannot assign to 'name' because it is a read-only property.
ts
array1[0] = 4;
array2[0] = 4;
Cannot assign to '0' because it is a read-only property.2540Cannot assign to '0' because it is a read-only property.
obj1.name = "raichu";
obj2.name = "raichu";
Cannot assign to 'name' because it is a read-only property.2540Cannot assign to 'name' because it is a read-only property.

Sự khác biệt giữa readonlyconst assertion

Cả hai đều có chức năng làm cho property của object thành readonly, nhưng có các điểm khác biệt sau.

readonly có thể áp dụng cho từng property

const assertion là khai báo cho toàn bộ object nên tất cả property đều bị ảnh hưởng, trong khi readonly có thể áp dụng chỉ cho những property cần thiết.

const assertion có thể áp dụng readonly đệ quy

Hành vi khác nhau khi có object lồng trong object. Ví dụ, giả sử có object như sau.

ts
type Country = {
name: string;
capitalCity: string;
};
 
type Continent = {
readonly name: string;
readonly canada: Country;
readonly us: 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",
},
};
ts
type Country = {
name: string;
capitalCity: string;
};
 
type Continent = {
readonly name: string;
readonly canada: Country;
readonly us: 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",
},
};

Ở đây tất cả property của type alias Continent đều là readonly. Do đó không thể làm những việc như sau.

ts
america.name = "African Continent";
Cannot assign to 'name' because it is a read-only property.2540Cannot assign to 'name' because it is a read-only property.
america.canada = {
Cannot assign to 'canada' because it is a read-only property.2540Cannot assign to 'canada' because it is a read-only property.
name: "Republic of Côte d'Ivoire",
capitalCity: "Yamoussoukro",
};
ts
america.name = "African Continent";
Cannot assign to 'name' because it is a read-only property.2540Cannot assign to 'name' because it is a read-only property.
america.canada = {
Cannot assign to 'canada' because it is a read-only property.2540Cannot assign to 'canada' because it is a read-only property.
name: "Republic of Côte d'Ivoire",
capitalCity: "Yamoussoukro",
};

Tuy nhiên, những việc như sau vẫn có thể thực hiện được mà không có vấn đề.

ts
america.canada.name = "Republic of Côte d'Ivoire";
america.canada.capitalCity = "Yamoussoukro";
ts
america.canada.name = "Republic of Côte d'Ivoire";
america.canada.capitalCity = "Yamoussoukro";

Điều này là do khi property có readonly là object, thì property của object đó không được làm thành readonly.

const assertion cố định tất cả property

Thêm as const.

ts
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;
ts
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;

Tương tự như readonly, không thể gán cho property ở top-level.

ts
america.name = "African Continent";
Cannot assign to 'name' because it is a read-only property.2540Cannot assign to 'name' because it is a read-only property.
america.canada = {
Cannot assign to 'canada' because it is a read-only property.2540Cannot assign to 'canada' because it is a read-only property.
name: "Republic of Côte d'Ivoire",
capitalCity: "Yamoussoukro",
};
ts
america.name = "African Continent";
Cannot assign to 'name' because it is a read-only property.2540Cannot assign to 'name' because it is a read-only property.
america.canada = {
Cannot assign to 'canada' because it is a read-only property.2540Cannot assign to 'canada' because it is a read-only property.
name: "Republic of Côte d'Ivoire",
capitalCity: "Yamoussoukro",
};

Không chỉ vậy, property của object con cũng được làm thành readonly.

ts
america.canada.name = "Republic of Côte d'Ivoire";
Cannot assign to 'name' because it is a read-only property.2540Cannot 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.2540Cannot assign to 'capitalCity' because it is a read-only property.
ts
america.canada.name = "Republic of Côte d'Ivoire";
Cannot assign to 'name' because it is a read-only property.2540Cannot 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.2540Cannot assign to 'capitalCity' because it is a read-only property.

Thông tin liên quan

📄️ Type assertion "as"

TypeScript có tính năng ghi đè type inference. Tính năng này được gọi là type assertion.

📄️ Readonly property của object type

Trong TypeScript, có thể đặt property của object thành read-only. Thêm modifier readonly vào property muốn đặt thành read-only. Khi cố gán giá trị cho property read-only, TypeScript compiler sẽ cảnh báo không thể gán.