Challenge - 5 Problems
Discriminated Union Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate2:00remaining
Output of discriminated union narrowing with switch
What is the output of the following TypeScript code when calling
handleShape({ kind: 'circle', radius: 5 })?Typescript
type Shape =
| { kind: 'circle'; radius: number }
| { kind: 'square'; size: number };
function handleShape(shape: Shape): string {
switch (shape.kind) {
case 'circle':
return `Circle with radius ${shape.radius}`;
case 'square':
return `Square with size ${shape.size}`;
}
}
console.log(handleShape({ kind: 'circle', radius: 5 }));Attempts:
2 left
💡 Hint
Look at the
kind property and how the switch narrows the type.✗ Incorrect
The switch statement uses the discriminated union's
kind property to narrow the type. When kind is 'circle', TypeScript knows shape has a radius property. So it returns the string with radius 5.❓ Predict Output
intermediate2:00remaining
Output of discriminated union narrowing with if statement
What will the following code output when calling
describeAnimal({ type: 'dog', barkVolume: 10 })?Typescript
type Animal =
| { type: 'dog'; barkVolume: number }
| { type: 'cat'; livesLeft: number };
function describeAnimal(animal: Animal): string {
if (animal.type === 'dog') {
return `Dog barks at volume ${animal.barkVolume}`;
} else {
return `Cat has ${animal.livesLeft} lives left`;
}
}
console.log(describeAnimal({ type: 'dog', barkVolume: 10 }));Attempts:
2 left
💡 Hint
Check how the
if condition narrows the union type.✗ Incorrect
The
if condition checks animal.type === 'dog', so inside the block TypeScript knows animal has barkVolume. It returns the correct string.❓ Predict Output
advanced2:00remaining
Output of function using discriminated union with exhaustive check
What is the output of the following code when calling
getArea({ kind: 'rectangle', width: 4, height: 3 })?Typescript
type Shape =
| { kind: 'circle'; radius: number }
| { kind: 'rectangle'; width: number; height: number };
function getArea(shape: Shape): number {
switch (shape.kind) {
case 'circle':
return Math.PI * shape.radius ** 2;
case 'rectangle':
return shape.width * shape.height;
default:
const _exhaustiveCheck: never = shape;
return _exhaustiveCheck;
}
}
console.log(getArea({ kind: 'rectangle', width: 4, height: 3 }));Attempts:
2 left
💡 Hint
Look at how the switch handles the 'rectangle' case and the default.
✗ Incorrect
The switch matches 'rectangle' and returns width * height = 4 * 3 = 12. The default case is never reached because all union members are handled.
❓ Predict Output
advanced2:00remaining
Output of discriminated union with nested narrowing
What will the following code output when calling
processEvent({ type: 'click', payload: { x: 10, y: 20 } })?Typescript
type Event =
| { type: 'click'; payload: { x: number; y: number } }
| { type: 'keypress'; payload: { key: string } };
function processEvent(event: Event): string {
if (event.type === 'click') {
const { x, y } = event.payload;
return `Clicked at (${x}, ${y})`;
} else if (event.type === 'keypress') {
return `Key pressed: ${event.payload.key}`;
}
return 'Unknown event';
}
console.log(processEvent({ type: 'click', payload: { x: 10, y: 20 } }));Attempts:
2 left
💡 Hint
Check how the nested payload is accessed after narrowing by type.
✗ Incorrect
The
if narrows event to the 'click' type, so payload has x and y. The function returns the coordinates correctly.🧠 Conceptual
expert2:00remaining
Why does the never type help in discriminated union narrowing?
In TypeScript, why is the
never type used in the default case of a switch statement handling a discriminated union?Attempts:
2 left
💡 Hint
Think about how TypeScript checks for completeness in union handling.
✗ Incorrect
Using
never in the default case forces TypeScript to check that all union members are handled. If a new member is added but not handled, the compiler shows an error.