When we construct new literal expressions with
- no literal types in that expression should be widened (e.g. no going from
"hello" tostring ) - object literals get
readonly properties - array literals become
readonly tuples
and here is a const assertion in action:
const email = 'john@gmail.com'; // type 'john@gmail.com'
const phones = [8494922901, 1238399293]; // type number[]
const session = { id: 123, name: 'x1keck323jKJdf1' };
// type
// {
// id: number;
// name: string;
// }
const username = 'John' as const; // type 'John'
const roles = [ 'read', 'write'] as const; // type readonly ["read", "write"]
const address = { street: 'Tokyo', country: 'Japan' } as const;
// type
// {
// readonly street: "Tokyo";
// readonly country: "Japan";
// }
const user = {
email,
phones,
session,
username,
roles,
address
} as const;
// {
// readonly email: "john@gmail.com";
// readonly phones: number[];
// readonly session: {
// id: number;
// name: string;
// };
// readonly username: "John";
// readonly roles: readonly ["read", "write"];
// readonly address: {
// readonly street: "Tokyo";
// readonly country: "Japan";
// };
// }
// With const assertion
// user.email = 'jim@gmail.com' // Error
// user.phones = []; // Error
user.phones.push(859324293);
// user.session = { name: 'new session name', id: 124 }; // Error
user.session.name = 'new session name';
// With const assertion + inner const assertion
// user.username = 'Jim'; // Error
// user.roles.push('ReadAndWrite'); // Error
// user.address.city = 'Osaka'; // Error
In addition, with
const roles = ['read', 'write', 'readAndWrite'] as const;
type Roles = typeof roles[number];
// equals to this
// type Roles = "read" | "write" | "readAndWrite"
// or even like this
type RolesInCapital = Capitalize<typeof roles[number]>;
// equals to this
// type RolesInCapital = "Read" | "Write" | "ReadAndWrite"
We use