Bird
Raised Fist0
Typescriptprogramming~30 mins

Exhaustive checking with never in Typescript - Mini Project: Build & Apply

Choose your learning style10 modes available
Exhaustive checking with never in TypeScript
📖 Scenario: You are building a simple program that handles different shapes. Each shape has a specific way to calculate its area. You want to make sure that if a new shape is added later, your program will remind you to handle it properly.
🎯 Goal: Create a TypeScript program that uses exhaustive checking with the never type to ensure all shape types are handled in a function.
📋 What You'll Learn
Create a union type called Shape with three shapes: circle, square, and rectangle
Create a variable called shape with a specific shape object
Create a function called calculateArea that uses a switch statement to handle each shape type
Use exhaustive checking with never in the calculateArea function to catch unhandled shapes
Print the area calculated by calculateArea
💡 Why This Matters
🌍 Real World
Exhaustive checking helps catch errors early when working with different types of data, such as shapes, events, or commands in real applications.
💼 Career
Understanding exhaustive checking with never is important for writing safe and maintainable TypeScript code, a valuable skill for frontend and backend developers.
Progress0 / 4 steps
1
Create the Shape union type and a shape variable
Create a union type called Shape with these exact types: { kind: 'circle', radius: number }, { kind: 'square', side: number }, and { kind: 'rectangle', width: number, height: number }. Then create a variable called shape with the value { kind: 'circle', radius: 5 }.
Typescript
Hint

Use a union type with | to combine the three shape types. Then create the shape variable with the exact object.

2
Add the calculateArea function skeleton
Create a function called calculateArea that takes a parameter shape of type Shape and returns a number. Inside the function, add a switch statement on shape.kind with empty cases for 'circle', 'square', and 'rectangle'.
Typescript
Hint

Define the function with the correct parameter and return type. Add a switch on shape.kind with cases for each shape kind.

3
Implement area calculations and add exhaustive checking
Inside the calculateArea function, return the correct area for each shape: for circle return Math.PI * shape.radius ** 2, for square return shape.side * shape.side, and for rectangle return shape.width * shape.height. After the switch, add a default case that assigns shape to a variable of type never to ensure exhaustive checking.
Typescript
Hint

Calculate each area using the correct formula. Use a default case with a never variable to catch unhandled shapes.

4
Print the area of the shape
Write a console.log statement to print the result of calling calculateArea with the shape variable.
Typescript
Hint

Call calculateArea(shape) and print the result using console.log.

Practice

(1/5)
1. What is the main purpose of using never in exhaustive checking in TypeScript?
easy
A. To declare a variable that can hold any value
B. To allow any type of value without restrictions
C. To ignore errors during compilation
D. To ensure all possible cases are handled in a switch or conditional

Solution

  1. Step 1: Understand the role of never in exhaustive checks

    never is used to represent values that should never occur, helping catch unhandled cases.
  2. Step 2: Connect never usage to exhaustive case handling

    By forcing a function to accept never, TypeScript ensures all cases are covered, or else a compile error occurs.
  3. Final Answer:

    To ensure all possible cases are handled in a switch or conditional -> Option D
  4. Quick Check:

    Exhaustive checking = catch all cases [OK]
Hint: Use never to catch missing cases in switch statements [OK]
Common Mistakes:
  • Thinking never allows any value
  • Using never to ignore errors
  • Confusing never with unknown type
2. Which of the following is the correct syntax for a helper function that uses never to enforce exhaustive checking?
easy
A. function assertNever(x: never): never { throw new Error('Unexpected value: ' + x); }
B. function assertNever(x: any): void { console.log(x); }
C. function assertNever(x: unknown): never { return x; }
D. function assertNever(x: never): void { return; }

Solution

  1. Step 1: Identify correct parameter and return types

    The helper function must accept a parameter of type never and return never because it throws an error.
  2. Step 2: Check function body matches expected behavior

    The function throws an error with the unexpected value, which is the standard pattern for exhaustive checks.
  3. Final Answer:

    function assertNever(x: never): never { throw new Error('Unexpected value: ' + x); } -> Option A
  4. Quick Check:

    Helper function with never param and throw = correct [OK]
Hint: Helper must take never and throw error to enforce checks [OK]
Common Mistakes:
  • Using any or unknown instead of never
  • Not throwing an error inside the function
  • Returning void instead of never
3. What will be the output of this TypeScript code?
type Shape = 'circle' | 'square';
function area(shape: Shape) {
  switch (shape) {
    case 'circle':
      return 3.14 * 2 * 2;
    // Missing case for 'square'
    default:
      return assertNever(shape);
  }
}

function assertNever(x: never): never {
  throw new Error('Unexpected shape: ' + x);
}

console.log(area('square'));
medium
A. Returns 12.56
B. Throws Error: Unexpected shape: square
C. Returns undefined
D. Compilation error due to missing case

Solution

  1. Step 1: Analyze switch cases and input

    The function handles 'circle' but not 'square', so at runtime, calling area('square') hits the default case.
  2. Step 2: Understand assertNever behavior at runtime

    The assertNever function throws an error with the unexpected shape, so the program throws a runtime error.
  3. Final Answer:

    Throws Error: Unexpected shape: square -> Option B
  4. Quick Check:

    Missing case causes runtime error when called [OK]
Hint: Missing case triggers runtime error when called [OK]
Common Mistakes:
  • Assuming missing case returns undefined
  • Thinking it returns a number for all inputs
  • Expecting compile error instead of runtime error
4. Identify the error in this TypeScript code using exhaustive checking:
type Direction = 'up' | 'down' | 'left';
function move(dir: Direction) {
  switch (dir) {
    case 'up':
      return 'Moving up';
    case 'down':
      return 'Moving down';
    default:
      return assertNever(dir);
  }
}

function assertNever(x: never): never {
  throw new Error('Unexpected direction: ' + x);
}
medium
A. Missing case for 'left' in switch statement
B. assertNever function has wrong parameter type
C. Switch statement should not have a default case
D. Function move should return void instead of string

Solution

  1. Step 1: Check all union cases in switch

    The type Direction has 'up', 'down', and 'left', but 'left' is missing in the switch.
  2. Step 2: Understand impact of missing case with assertNever

    Missing 'left' causes default to call assertNever with a string, which is not never, causing a compile error.
  3. Final Answer:

    Missing case for 'left' in switch statement -> Option A
  4. Quick Check:

    All union cases must be handled [OK]
Hint: Check all union cases explicitly to avoid errors [OK]
Common Mistakes:
  • Ignoring missing union cases
  • Thinking default case covers all safely
  • Wrong assertNever parameter type
5. Given this code, how can you modify it to ensure exhaustive checking for all Status values?
type Status = 'success' | 'error' | 'loading';

function handleStatus(status: Status) {
  switch (status) {
    case 'success':
      return 'Done';
    case 'error':
      return 'Failed';
    // Missing 'loading' case
    default:
      return assertNever(status);
  }
}

function assertNever(x: never): never {
  throw new Error('Unexpected status: ' + x);
}
hard
A. Change the type Status to include only 'success' and 'error'
B. Remove the default case and rely on TypeScript errors
C. Add a case for 'loading' in the switch statement
D. Change assertNever parameter type to any

Solution

  1. Step 1: Identify missing union case in switch

    The 'loading' case is missing, so the switch is not exhaustive.
  2. Step 2: Add missing case to ensure all Status values are handled

    Adding case 'loading': with appropriate return ensures exhaustive checking and no runtime errors.
  3. Final Answer:

    Add a case for 'loading' in the switch statement -> Option C
  4. Quick Check:

    All union members must have cases [OK]
Hint: Add missing union cases to switch for full coverage [OK]
Common Mistakes:
  • Removing default case without adding missing cases
  • Changing type to avoid handling all cases
  • Using any instead of never in assertNever
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard