A discriminated union is a special type of union where each member has a common property with a unique literal type. This property helps TypeScript narrow down the type safely.
Click to reveal answer
beginner
Why use discriminated unions for state machines?
They let you clearly define each state with a unique 'tag' property, making it easy to check the current state and handle transitions safely with TypeScript's type checking.
Click to reveal answer
intermediate
Example of a discriminated union for a traffic light state machine?
type TrafficLight =
| { state: 'red'; duration: number }
| { state: 'yellow'; duration: number }
| { state: 'green'; duration: number };
Each object has a 'state' property that discriminates the union.
Click to reveal answer
intermediate
How does TypeScript help when switching on a discriminated union?
TypeScript narrows the type inside each case block based on the discriminant property, so you get autocompletion and type safety for that specific state.
Click to reveal answer
advanced
What happens if you forget to handle a state in a discriminated union switch?
TypeScript can warn you if you use the 'never' type in a default case, helping you catch missing cases and making your state machine safer.
Click to reveal answer
What property is essential in a discriminated union to distinguish states?
AA numeric index
BA method to change states
CA common property with unique literal values
DAn optional property
✗ Incorrect
The discriminant property is a common property with unique literal values that helps TypeScript identify the current type.
In a state machine using discriminated unions, how do you typically check the current state?
AUsing if statements on random properties
BBy using a global variable
CBy checking the object's prototype
DUsing a switch statement on the discriminant property
✗ Incorrect
A switch on the discriminant property lets TypeScript narrow the type safely for each state.
What benefit does TypeScript provide when handling all states in a discriminated union?
AIt ensures all cases are handled, preventing runtime errors
BIt automatically fixes bugs
CIt runs the code faster
DIt hides unused states
✗ Incorrect
TypeScript can warn about missing cases, helping prevent bugs from unhandled states.
Which of these is a valid discriminated union type for a simple state machine?
Hint: Discriminant property must be named exactly 'type' [OK]
Common Mistakes:
Using different property names like 'status' or 'state'
Mixing properties between states incorrectly
Adding data to loading state incorrectly
3.
Given the following TypeScript code, what will be the output?
type State =
| { type: 'idle' }
| { type: 'loading' }
| { type: 'success'; data: string };
function getMessage(state: State): string {
switch (state.type) {
case 'idle':
return 'Waiting...';
case 'loading':
return 'Loading...';
case 'success':
return `Data: ${state.data}`;
}
}
console.log(getMessage({ type: 'success', data: 'Hello' }));
medium
A. Error: Property 'data' does not exist
B. Loading...
C. Waiting...
D. Data: Hello
Solution
Step 1: Analyze the input state
The input state is { type: 'success', data: 'Hello' }, matching the 'success' case.
Step 2: Follow the switch case logic
For 'success', the function returns `Data: ${state.data}`, which becomes 'Data: Hello'.
Final Answer:
Data: Hello -> Option D
Quick Check:
State 'success' returns data string [OK]
Hint: Match type in switch to get correct output [OK]
Common Mistakes:
Confusing 'success' with 'loading' or 'idle'
Expecting an error accessing 'data' without checking type
Ignoring template string interpolation
4.
Identify the error in this discriminated union state machine code:
type State =
| { type: 'start' }
| { type: 'end'; result: number };
function process(state: State) {
if (state.type === 'start') {
console.log('Starting');
} else {
console.log('Result is ' + state.result);
}
}
process({ type: 'start' });
medium
A. No error; code runs and prints 'Starting'.
B. Error: Accessing 'result' on 'start' state causes runtime error.
C. Error: Missing return type annotation on function.
D. Error: 'type' property should be optional.
Solution
Step 1: Check the state type conditions
The function checks if state.type === 'start' and logs 'Starting'.
Step 2: Confirm safe access to 'result'
In the else branch, state.result is accessed only if state.type !== 'start', so it must be 'end' with result.
Final Answer:
No error; code runs and prints 'Starting'. -> Option A
Quick Check:
Type narrowing prevents invalid property access [OK]
Hint: Check type guards before accessing state-specific properties [OK]
Common Mistakes:
Assuming accessing 'result' on 'start' state causes error
Expecting return type annotation is mandatory
Thinking 'type' property should be optional
5.
You want to extend a discriminated union state machine to handle an error state with an optional message. Which is the best way to define this state to keep type safety and allow missing message?