Bird
Raised Fist0
Typescriptprogramming~10 mins

Type-safe API response handling in Typescript - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Type-safe API response handling
Start API call
↓
Fetch response
↓
Parse JSON
↓
Validate type
↓
Use data
↓
End
This flow shows how an API call is made, the response is parsed, then checked for correct type before using or handling errors.
Execution Sample
Typescript
async function fetchUser() {
  const res = await fetch('/api/user');
  const data = await res.json() as User;
  if (data && data.id && data.name) {
    return data;
  } else {
    throw new Error('Invalid data');
  }
}
This code fetches user data from an API, asserts its type, and checks required fields before returning or throwing an error.
Execution Table
StepActionEvaluationResult
1Call fetch('/api/user')Fetch promise startsPending response
2Await responseResponse received{ status: 200, body: JSON }
3Parse JSONConvert response to object{ id: 1, name: 'Alice' }
4Type assertion as UserAssume data is User typedata typed as User
5Check data.id and data.nameBoth exist?True
6Return dataUser object returned{ id: 1, name: 'Alice' }
ExitEnd functionSuccessful returnUser data ready to use
💡 Function ends after returning valid user data or throwing error if invalid
Variable Tracker
VariableStartAfter Step 3After Step 4Final
resundefined{ status: 200, body: JSON }{ status: 200, body: JSON }{ status: 200, body: JSON }
dataundefined{ id: 1, name: 'Alice' }typed as User{ id: 1, name: 'Alice' }
Key Moments - 2 Insights
Why do we check data.id and data.name after asserting the type?
Because 'as User' only tells TypeScript to treat data as User but does not verify the actual content at runtime. The check ensures the data really has required fields (see step 5 in execution_table).
What happens if the API returns data missing 'name'?
The condition in step 5 fails, so the function throws an error instead of returning invalid data, preventing bugs later.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table, what is the value of 'data' after step 3?
Aundefined
B{ id: 1, name: 'Alice' }
CFetch promise
DError thrown
💡 Hint
Check the 'Evaluation' and 'Result' columns at step 3 in execution_table.
At which step does the code verify the data has required fields?
AStep 2
BStep 4
CStep 5
DStep 6
💡 Hint
Look for the condition check in execution_table rows.
If the API returned { id: 2 } without 'name', what would happen?
AError thrown at step 5
BType assertion fails at step 4
CData returned successfully
DFetch fails at step 1
💡 Hint
Refer to key_moments about missing fields and step 5 condition.
Concept Snapshot
Type-safe API response handling:
- Fetch data with fetch()
- Parse JSON with res.json()
- Use 'as Type' to assert type
- Check required fields at runtime
- Return data if valid, else throw error
Ensures safe use of API data in TypeScript
Full Transcript
This example shows how to safely handle API responses in TypeScript. First, we call fetch to get data from the server. Then we parse the response as JSON. We tell TypeScript to treat the data as a specific type using 'as User'. However, this does not check the data's actual shape, so we manually verify required fields like 'id' and 'name'. If the data is valid, we return it. Otherwise, we throw an error to avoid using bad data. This approach helps prevent bugs by combining type assertions with runtime checks.

Practice

(1/5)
1. What is the main benefit of using type-safe API response handling in TypeScript?
easy
A. It makes the API faster to respond.
B. It removes the need for testing API responses.
C. It automatically fixes bugs in the API.
D. It helps catch errors early by defining expected data shapes.

Solution

  1. Step 1: Understand type safety purpose

    Type-safe handling means defining what data should look like before using it.
  2. Step 2: Identify the benefit

    This helps catch mistakes early, like missing or wrong data types, before running the program.
  3. Final Answer:

    It helps catch errors early by defining expected data shapes. -> Option D
  4. Quick Check:

    Type safety = Early error detection [OK]
Hint: Type safety means catching errors before running code [OK]
Common Mistakes:
  • Thinking type safety improves API speed
  • Believing it fixes bugs automatically
  • Assuming it replaces testing
2. Which TypeScript syntax correctly defines a generic function to fetch API data with a type-safe response?
easy
A. function fetchData(url: string): Promise<any> { /* ... */ }
B. function fetchData<T>(url: string): Promise<T> { /* ... */ }
C. function fetchData<T>(url: string): T { /* ... */ }
D. function fetchData(url: string): T { /* ... */ }

Solution

  1. Step 1: Understand generic function syntax

    Generic functions use <T> to represent a type parameter, allowing flexible typing.
  2. Step 2: Check return type for async fetch

    Fetching data returns a Promise of type T, so the return type must be Promise<T>.
  3. Final Answer:

    function fetchData<T>(url: string): Promise<T> { /* ... */ } -> Option B
  4. Quick Check:

    Generic + Promise = function fetchData<T>(url: string): Promise<T> { /* ... */ } [OK]
Hint: Generic fetch returns Promise of type T [OK]
Common Mistakes:
  • Returning T directly instead of Promise<T>
  • Missing generic <T> in function definition
  • Using Promise<any> loses type safety
3. Given this TypeScript code, what will be the output?
interface User { id: number; name: string; }

async function getUser(): Promise<User> {
  return { id: 1, name: "Alice" };
}

getUser().then(user => console.log(user.name));
medium
A. { id: 1, name: "Alice" }
B. 1
C. "Alice"
D. undefined

Solution

  1. Step 1: Analyze the getUser function

    It returns a Promise resolving to an object with id 1 and name "Alice".
  2. Step 2: Check the then callback

    The callback logs user.name, which is "Alice".
  3. Final Answer:

    "Alice" -> Option C
  4. Quick Check:

    user.name = "Alice" [OK]
Hint: Promise resolves to object; log property name [OK]
Common Mistakes:
  • Logging user instead of user.name
  • Confusing id with name
  • Expecting entire object printed
4. Identify the error in this TypeScript code for type-safe API response handling:
interface ApiResponse { success: boolean; data: string; }

async function fetchApi(): Promise<ApiResponse> {
  const response = await fetch('https://api.example.com');
  const json = await response.json();
  return json;
}
medium
A. Missing type assertion or validation for json before returning.
B. The fetch call should not use await.
C. The interface ApiResponse is missing a constructor.
D. The function should return void instead of Promise<ApiResponse>.

Solution

  1. Step 1: Check how json is handled

    json is returned directly without confirming it matches ApiResponse shape.
  2. Step 2: Understand type safety requirement

    TypeScript needs either a type assertion or runtime validation to ensure json fits ApiResponse.
  3. Final Answer:

    Missing type assertion or validation for json before returning. -> Option A
  4. Quick Check:

    Validate json shape before return [OK]
Hint: Always validate or assert API response type [OK]
Common Mistakes:
  • Assuming fetch json is automatically typed
  • Ignoring need for runtime checks
  • Misunderstanding async/await usage
5. You want to create a type-safe function that fetches a list of users from an API and returns only users with an active status. Which approach correctly applies type-safe API response handling?
hard
A. Define interface User with 'active' boolean, fetch data as Promise, then filter users by active before returning.
B. Fetch data as Promise<any>, filter users by active without type checking, then cast to User[].
C. Define interface User without 'active', fetch data as Promise, then filter users by active.
D. Fetch data as Promise, return data without filtering to keep type safety.

Solution

  1. Step 1: Define User interface including 'active' property

    To filter by active status, the User type must include an 'active' boolean field.
  2. Step 2: Fetch data as Promise<User[]> and filter

    Fetching with correct type ensures type safety; filtering users by active keeps the result accurate and typed.
  3. Final Answer:

    Define interface User with 'active' boolean, fetch data as Promise<User[]>, then filter users by active before returning. -> Option A
  4. Quick Check:

    Correct interface + typed fetch + filter = Define interface User with 'active' boolean, fetch data as Promise, then filter users by active before returning. [OK]
Hint: Include all needed fields in interface before filtering [OK]
Common Mistakes:
  • Casting any to User[] without checks
  • Filtering on missing properties in interface
  • Returning unfiltered data losing requirements
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