Literal types allow you to specify exact values that a variable, property, or parameter can contain. Instead of allowing every string or number, a literal type restricts the value to specific values.
A literal type represents one exact value.
let status: "active";
status = "active";
The variable can contain only the exact string
"active".
A string literal type restricts a variable to one exact string.
let direction: "left";
direction = "left";
// direction = "right"; // Error
Multiple literal values can be combined using a union.
let direction:
"left" |
"right";
direction = "left";
direction = "right";
Only "left" or "right" is allowed.
Literal types are commonly used for status values.
let status:
"pending" |
"approved" |
"rejected";
status = "pending";
status = "approved";
A value that is not included in the literal type is rejected.
let status:
"pending" |
"approved" |
"rejected";
status = "pending";
// status = "completed"; // Error
Literal types can also represent exact numbers.
let score: 100;
score = 100;
// score = 90; // Error
Multiple number literals can be combined with a union.
let rating:
1 |
2 |
3 |
4 |
5;
rating = 5;
rating = 3;
Only the specified numbers are accepted.
Boolean literal types can represent exactly
true or false.
let active: true;
active = true;
// active = false; // Error
Both boolean values can be allowed using a union.
let active:
true |
false;
active = true;
active = false;
In practice, boolean is usually used when both
values are allowed.
Literal types can be used directly with variables.
let color:
"red" |
"green" |
"blue";
color = "red";
color = "blue";
Function parameters can accept only specific literal values.
function move(
direction:
"left" |
"right"
) {
console.log(
direction
);
}
move("left");
move("right");
TypeScript rejects arguments that are not part of the literal type.
function move(
direction:
"left" |
"right"
) {
console.log(direction);
}
move("left");
// move("up"); // Error
A function can be required to return one of several specific literal values.
function getStatus():
"success" |
"error" {
return "success";
}
console.log(
getStatus()
);
Interfaces can use literal types for their properties.
interface User {
name: string;
role:
"admin" |
"student";
}
const user: User = {
name: "Amit",
role: "student"
};
Literal types are useful for defining fixed user roles.
type Role =
"admin" |
"teacher" |
"student";
let role: Role;
role = "admin";
role = "teacher";
role = "student";
Literal types can represent fixed course levels.
type Level =
"beginner" |
"intermediate" |
"advanced";
let level: Level;
level = "beginner";
level = "advanced";
Literal types can restrict an HTTP method to known values.
type HttpMethod =
"GET" |
"POST" |
"PUT" |
"DELETE";
let method: HttpMethod;
method = "GET";
method = "POST";
Literal types are useful for UI component variants.
type ButtonVariant =
"primary" |
"secondary" |
"danger";
let variant: ButtonVariant;
variant = "primary";
variant = "danger";
React component props can use literal types to restrict accepted values.
interface ButtonProps {
title: string;
variant:
"primary" |
"secondary" |
"danger";
}
function Button(
props: ButtonProps
) {
return (
<button>
{props.title}
</button>
);
}
Button({
title: "Save",
variant: "primary"
});
React Native components can use literal types for component variants.
interface ButtonProps {
title: string;
variant:
"primary" |
"secondary" |
"danger";
}
const Button = (
props: ButtonProps
) => {
return (
<View>
<Text>
{props.title}
</Text>
</View>
);
};
Type aliases make repeated literal type definitions easier to manage.
type Status =
"pending" |
"approved" |
"rejected";
let status1: Status =
"pending";
let status2: Status =
"approved";
Literal values can help TypeScript narrow the possible structure of an object.
interface Admin {
role: "admin";
name: string;
}
interface Student {
role: "student";
name: string;
}
type User =
Admin | Student;
function showUser(
user: User
) {
if (user.role === "admin") {
console.log(
"Admin:",
user.name
);
} else {
console.log(
"Student:",
user.name
);
}
}
A literal property can act as a discriminator between different object types.
interface Success {
status: "success";
data: string;
}
interface ErrorResponse {
status: "error";
message: string;
}
type Response =
Success |
ErrorResponse;
function handleResponse(
response: Response
) {
if (
response.status ===
"success"
) {
console.log(
response.data
);
} else {
console.log(
response.message
);
}
}
A const variable can preserve a literal value
in situations where a let variable may be widened.
const status =
"success";
let message =
"success";
Literal inference can be useful when working with fixed values.
API response states can be represented using literal types.
type ApiStatus =
"loading" |
"success" |
"error";
let status: ApiStatus =
"loading";
status = "success";
status = "error";
A common mistake is assigning a value that is not part of the literal union.
type Status =
"active" |
"inactive";
let status: Status;
status = "active";
// status = "pending"; // Error
Only the values declared in the literal type are accepted.
Literal types are useful when the possible values are known and limited.
A general type accepts many values, while a literal type accepts only specific values.
let color: string;
color = "red";
color = "green";
color = "anything";
let fixedColor:
"red" |
"green";
fixedColor = "red";
fixedColor = "green";
// fixedColor = "blue"; // Error
type Role =
"admin" |
"teacher" |
"student";
type Status =
"active" |
"inactive";
type Level =
"beginner" |
"intermediate" |
"advanced";
interface User {
id: number;
name: string;
role: Role;
status: Status;
level: Level;
}
const user: User = {
id: 101,
name: "Amit",
role: "student",
status: "active",
level: "beginner"
};
function showUser(
user: User
) {
console.log(
"Name:",
user.name
);
console.log(
"Role:",
user.role
);
console.log(
"Status:",
user.status
);
console.log(
"Level:",
user.level
);
}
showUser(user);
Literal types allow TypeScript to restrict values to specific strings, numbers, booleans, or combinations of those values.
type Status =
"pending" |
"approved" |
"rejected";
let status: Status =
"pending";
They are especially useful for fixed choices, component props, API states, and discriminated unions.
true or false.Question: Which of the following is a valid TypeScript literal type?