Hone logo
Hone
Problems

Type-Safe API Client in TypeScript

Building robust and maintainable applications often involves interacting with external APIs. This challenge asks you to create a type-safe API client in TypeScript, ensuring that your code is protected from common errors related to API responses and data structures. A type-safe client will significantly improve developer experience and reduce runtime errors.

Problem Description

You are tasked with creating a TypeScript API client that interacts with a simplified weather API. The API provides weather data for a given city. The client should be type-safe, meaning it uses TypeScript's type system to ensure that the data received from the API matches the expected structure.

What needs to be achieved:

  • Create a TypeScript class named WeatherApiClient.
  • The class should have a method getWeather(city: string) that fetches weather data for the specified city.
  • The getWeather method should return a Promise that resolves to a WeatherData interface.
  • The WeatherData interface should define the structure of the expected weather data (see below).
  • Implement a mock API endpoint to simulate the API response. This mock endpoint should return JSON data that conforms to the WeatherData interface.
  • Handle potential errors during the API call (e.g., network errors, invalid city).

Key Requirements:

  • Type Safety: The client must be type-safe, using TypeScript interfaces to define the expected data structure.
  • Promise-based: The getWeather method must return a Promise.
  • Error Handling: The client should handle potential errors gracefully and reject the Promise with an appropriate error message.
  • Mock API: A mock API endpoint should be used for testing purposes. Do not use a real external API.

Expected Behavior:

  • When getWeather(city) is called with a valid city name, the Promise should resolve with a WeatherData object.
  • When getWeather(city) is called with an invalid city name (e.g., an empty string or a city that doesn't exist in the mock API), the Promise should reject with an error message indicating that the city is invalid.
  • If a network error occurs during the API call, the Promise should reject with an error message indicating a network issue.

WeatherData Interface:

interface WeatherData {
  city: string;
  temperature: number;
  condition: string;
  windSpeed: number;
}

Examples

Example 1:

Input: WeatherApiClient.getWeather("London")
Output: { city: "London", temperature: 15, condition: "Cloudy", windSpeed: 10 }
Explanation: The API returns weather data for London, which is then returned by the Promise.

Example 2:

Input: WeatherApiClient.getWeather("")
Output: Promise rejected with error: "Invalid city name."
Explanation: An empty city name is considered invalid, so the Promise is rejected.

Example 3:

Input: WeatherApiClient.getWeather("Atlantis")
Output: Promise rejected with error: "City not found."
Explanation: Atlantis is not a valid city in the mock API, so the Promise is rejected.

Constraints

  • The mock API endpoint should return data in JSON format.
  • The getWeather method should not take more than 500ms to execute (even with the mock API).
  • The WeatherData interface must be defined as specified above.
  • Error messages should be clear and informative.

Notes

  • You can use fetch or any other HTTP client library to make the API request. For simplicity, fetch is recommended.
  • Consider using async/await to simplify the asynchronous code.
  • The mock API endpoint can be implemented using a simple setTimeout to simulate network latency.
  • Focus on creating a clean, well-structured, and type-safe API client. Code readability and maintainability are important.
  • Think about how you would handle different HTTP status codes (e.g., 404 Not Found) in a real-world scenario. For this exercise, focus on the core type-safety and error handling aspects.
Loading editor...
typescript