Typescript Foundations / Advanced Types

as const

πŸ”’ as const in TypeScript

as const tells TypeScript to treat a value as immutable and as specific as possible.

It prevents TypeScript from widening values like "admin" to string or 10 to number.


πŸ”Ή Without as const

const role = "admin";

TypeScript can infer:

string

With as const:

const role = "admin" as const;

The type becomes:

"admin"

So "admin" is a literal type, not just a general string.


🎯 Why Use as const?

It is useful when you want values to be fixed and exact.

const status = "success" as const;

function handleStatus(status: "success" | "error") {
  // ...
}

handleStatus(status); // βœ…

Without as const, TypeScript may treat a mutable value as string, which can cause type errors.


πŸ“¦ With Objects

const user = {
  name: "Bhaskar",
  role: "admin"
} as const;

TypeScript treats it approximately as:

{
  readonly name: "Bhaskar";
  readonly role: "admin";
}

So you cannot modify the properties:

user.role = "user"; // ❌ Error

πŸ“š With Arrays

const roles = ["admin", "user", "guest"] as const;

Instead of:

string[]

TypeScript infers a readonly tuple:

readonly ["admin", "user", "guest"]

You cannot modify it:

roles.push("editor"); // ❌ Error

πŸ’‘ Extracting a Union Type

This is one of the most useful patterns:

const roles = ["admin", "user", "guest"] as const;

type Role = typeof roles[number];

Now:

type Role = "admin" | "user" | "guest";

You can use it elsewhere:

function setRole(role: Role) {
  console.log(role);
}

setRole("admin"); // βœ…
setRole("editor"); // ❌ Error

⚠️ const vs as const

They are not the same.

const role = "admin";

const prevents reassignment of the variable, but as const tells TypeScript to preserve the exact literal value and make objects/arrays readonly.

const user = {
  name: "Bhaskar"
};

user.name = "Rahul"; // βœ…

But:

const user = {
  name: "Bhaskar"
} as const;

user.name = "Rahul"; // ❌

🧠 Remember

as const makes values as specific and readonly as possible.

It is especially useful for literal types, configuration objects, readonly arrays, and creating union types from arrays.