A discriminated union is a special kind of union type that uses a common literal property (called the discriminant) to tell which type in the union is being used. This helps TypeScript safely narrow down the type.
Click to reveal answer
beginner
Why do discriminated unions use a common literal property?
The common literal property acts like a tag or label that tells TypeScript which shape or variant of the union is active. This makes it easy to check the property and get correct type information.
Click to reveal answer
beginner
Example: What does this code do?
type Shape = { kind: 'circle'; radius: number } | { kind: 'square'; size: number };
This defines a discriminated union called Shape. It can be either a circle with a radius or a square with a size. The 'kind' property tells which shape it is.
Click to reveal answer
intermediate
How does TypeScript narrow types with discriminated unions in a switch statement?
When you switch on the discriminant property (like 'kind'), TypeScript knows which type you are working with in each case block, so it allows only the properties of that specific type.
Click to reveal answer
intermediate
What happens if you forget to handle a case in a discriminated union switch?
TypeScript can warn you if you use the 'never' type in a default case to catch unhandled cases. This helps you write safer code by ensuring all variants are handled.
Click to reveal answer
What is the key property called that discriminated unions use to identify the type?
ADiscriminant
BIdentifier
CSelector
DMarker
✗ Incorrect
The key property is called the discriminant. It is a literal property used to distinguish types in the union.
Given this type:
type Pet = { type: 'dog'; bark: () => void } | { type: 'cat'; meow: () => void };
What will TypeScript know inside if(pet.type === 'dog') block?
Apet has both bark and meow methods
Bpet has a meow method
Cpet has a bark method
Dpet has no methods
✗ Incorrect
Inside the if block, TypeScript knows pet is the dog type, so it has a bark method.
Which TypeScript feature helps ensure all cases of a discriminated union are handled?
Aany type
Bvoid type
Cunknown type
Dnever type
✗ Incorrect
The never type is used to catch unhandled cases in discriminated unions, helping with exhaustiveness checking.
What happens if you use a discriminated union without a common literal property?
ATypeScript can still narrow types perfectly
BTypeScript cannot narrow types automatically
CIt causes a runtime error
DIt converts the union to any
✗ Incorrect
Without a common literal property, TypeScript cannot automatically narrow the union types.
Which of these is a valid discriminant property value for a discriminated union?
Astring literal
Bboolean
Cnumber
Dobject
✗ Incorrect
The discriminant property must be a literal type, usually a string literal, to distinguish union members.
Explain what a discriminated union is and how it helps with type safety in TypeScript.
Think about how a special property helps TypeScript know exactly which type you are working with.
You got /4 concepts.
Describe how you would use a switch statement with a discriminated union to handle different cases.
Imagine you have a shape type with different kinds and want to do something different for each kind.
You got /4 concepts.
Practice
(1/5)
1.
What is the main purpose of a discriminated union in TypeScript?
easy
A. To automatically convert types at runtime
B. To create a union of unrelated primitive types
C. To enforce a single type for all variables
D. To distinguish between different object types using a common property
Solution
Step 1: Understand discriminated unions
Discriminated unions use a shared property (called the discriminant) to identify which type an object belongs to.
Step 2: Purpose of discriminated unions
This helps TypeScript safely narrow types in code by checking that property.
Final Answer:
To distinguish between different object types using a common property -> Option D
Quick Check:
Discriminated union = common property to tell types apart [OK]
Hint: Look for a shared property that identifies each type [OK]
Which of the following is the correct syntax to define a discriminated union type in TypeScript?
type Shape = ?
easy
A. type Shape = { kind: 'circle'; radius: number } | { kind: 'square'; side: number }
B. type Shape = { radius: number } & { side: number }
C. type Shape = { kind: string; radius?: number; side?: number }
D. type Shape = { circle: number } | { square: number }
Solution
Step 1: Identify discriminant property
type Shape = { kind: 'circle'; radius: number } | { kind: 'square'; side: number } uses a common property kind with literal types ('circle' or 'square') to discriminate.
Step 2: Check union structure
type Shape = { kind: 'circle'; radius: number } | { kind: 'square'; side: number } correctly uses a union of two object types distinguished by kind.
Final Answer:
type Shape = { kind: 'circle'; radius: number } | { kind: 'square'; side: number } -> Option A
Quick Check:
Discriminated union = union with common literal property [OK]
Hint: Look for union with a shared literal property for discrimination [OK]
Common Mistakes:
Using intersection (&) instead of union (|)
Missing literal type for discriminant property
Using optional properties without discriminant
3.
What will be the output of the following TypeScript code?
type Animal =
| { type: 'dog'; barkVolume: number }
| { type: 'cat'; livesLeft: number };
function describe(animal: Animal) {
switch (animal.type) {
case 'dog':
return `Dog barks at volume ${animal.barkVolume}`;
case 'cat':
return `Cat has ${animal.livesLeft} lives left`;
}
}
console.log(describe({ type: 'cat', livesLeft: 7 }));
medium
A. Cat has 7 lives left
B. Dog barks at volume undefined
C. TypeError at runtime
D. Cat has undefined lives left
Solution
Step 1: Analyze the input object
The input is { type: 'cat', livesLeft: 7 }, so the type is 'cat'.
Step 2: Follow the switch case
The switch matches 'cat' case and returns `Cat has ${animal.livesLeft} lives left`, which becomes 'Cat has 7 lives left'.
Final Answer:
Cat has 7 lives left -> Option A
Quick Check:
Switch on discriminant returns correct string [OK]
Hint: Match the discriminant property in switch to get output [OK]
Common Mistakes:
Confusing 'dog' and 'cat' cases
Expecting runtime error due to union
Ignoring the discriminant property
4.
Identify the error in this TypeScript code using discriminated unions:
type Vehicle =
| { kind: 'car'; wheels: number }
| { kind: 'bike'; pedals: number };
function getWheels(vehicle: Vehicle) {
if (vehicle.kind === 'car') {
return vehicle.wheels;
} else {
return vehicle.wheels;
}
}
medium
A. Function should use switch instead of if
B. Property 'wheels' does not exist on type 'bike' object
C. Incorrect discriminant property name
D. Missing return type annotation on function
Solution
Step 1: Check property access in else branch
In the else branch, the code accesses vehicle.wheels, but bike type has no wheels property.
Step 2: Understand TypeScript error
This causes a type error because wheels is not defined for { kind: 'bike'; pedals: number }.
Final Answer:
Property 'wheels' does not exist on type 'bike' object -> Option B
Quick Check:
Accessing wrong property on union member causes error [OK]
Hint: Check property exists on all union members before access [OK]
Common Mistakes:
Assuming all union members share same properties
Ignoring TypeScript error messages
Thinking switch is mandatory over if
5.
Given the following discriminated union, how can you safely add a new shape type rectangle with width and height properties and update the area function accordingly?
type Shape =
| { kind: 'circle'; radius: number }
| { kind: 'square'; side: number };
function area(shape: Shape): number {
switch (shape.kind) {
case 'circle':
return Math.PI * shape.radius ** 2;
case 'square':
return shape.side ** 2;
}
}
hard
A. Add { kind: 'rectangle'; width: number; height: number } to Shape union and replace switch with if-else
B. Add { kind: 'rectangle'; width: number; height: number } to Shape union but no change needed in area function
C. Add { kind: 'rectangle'; width: number; height: number } to Shape union and add case 'rectangle' in switch returning width * height
D. Add { kind: 'rectangle'; width: number; height: number } to Shape union and remove existing cases
Solution
Step 1: Extend the union type
Add the new shape type with discriminant kind: 'rectangle' and properties width and height to the Shape union.
Step 2: Update the area function
Add a new case in the switch for 'rectangle' that returns shape.width * shape.height to correctly calculate the area.
Final Answer:
Add { kind: 'rectangle'; width: number; height: number } to Shape union and add case 'rectangle' in switch returning width * height -> Option C
Quick Check:
Extend union and handle new case in switch [OK]
Hint: Add new type to union and handle it in switch [OK]
Common Mistakes:
Forgetting to update the function for new type
Removing existing cases accidentally
Not using discriminant property in new type
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.