Literal discriminant
- TypeScript course
- Advanced
- Lesson 30/57
- 4 min
Learn to discriminate with literal fields.
Literal discriminant
The discriminant field's value is a literal type; each member carries its own unique literal value. A value like kind: "circle" tells TypeScript which member is present. Using literal values makes the narrowing precise and safe.
type Event =
| { type: "click"; x: number; y: number }
| { type: "scroll"; offset: number };
function handle(e: Event) {
if (e.type === "click") {
console.log(e.x, e.y); // click member
} else {
console.log(e.offset); // scroll member
}
}Narrowing with literal values
When the discriminant is a literal, TypeScript narrows the union with an equality check. The condition e.type === "click" reduces the Event union to only the click member; inside the condition e.x and e.y are safe to use.
function handle(e: Event) {
if (e.type === "click") {
e.x; // number (click member)
e.y; // number (click member)
}
// Here e.x is not accessible: e is the full Event again
}Practice Handle events with a literal discriminant
Define the Event discriminated union type: "click" (x: number, y: number) and "scroll" (offset: number) members, with a type discriminant field. Write a handle(e: Event): string function. If e.type === "click", return `click at ${e.x},${e.y}`; otherwise return `scroll ${e.offset}`. Print results via console.log(handle({ type: "click", x: 10, y: 20 })) and console.log(handle({ type: "scroll", offset: 5 })).
Starter code
// Event discriminated union türünü tanımla (type discriminant, click ve scroll üyeleri)
// handle(e: Event): string fonksiyonunu type kontrolüyle yaz
// click ve scroll olaylarının sonuçlarını yazdırSample solution
type Event =
| { type: "click"; x: number; y: number }
| { type: "scroll"; offset: number };
function handle(e: Event): string {
if (e.type === "click") {
return `click at ${e.x},${e.y}`;
}
return `scroll ${e.offset}`;
}
console.log(handle({ type: "click", x: 10, y: 20 }));
console.log(handle({ type: "scroll", offset: 5 }));Expected output
click at 10,20 scroll 5
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 What type should the discriminant field's value be?
- Any number
- An optional value
- A different literal value in each member Correct answer
- The same value in each member
Explanation: The discriminant field takes a different literal value in each member; this lets TypeScript narrow the union to a single member with an equality check.
2 Narrowing with a literal discriminant
type Event =
| { type: "click"; x: number; y: number }
| { type: "scroll"; offset: number };
function handle(e: Event) {
if (e.type === ____) {
return e.x + e.y;
}
return e.offset;
}
type Event =
| { type: "click"; x: number; y: number }
| { type: "scroll"; offset: number };
function handle(e: Event) {
if (e.type === "click") {
return e.x + e.y;
}
return e.offset;
}
Explanation: Checking the discriminant literal "click" narrows the union to the click member; inside the condition e.x and e.y are safe to use.
3 Literal discriminant parts
| Term | Meaning |
|---|---|
Literal değer |
unique in each member |
e.type === "click" |
narrows to click member |
Discriminant alan |
of literal type |
Eşitlik kontrolü |
narrowing method |