Stop Using `any`: Why TypeScript Interfaces Matter
It's tempting to use any when parsing unknown JSON from an API. But doing so defeats the entire purpose of TypeScript. Here is how to wrangle messy data properly.
The Problem with `any`
When you fetch data using const response = await fetch('/api/data').then(res => res.json()), the resulting response object is essentially cast to any. This means the TypeScript compiler has no idea what properties exist on the object.
If the API returns a property called first_name, but you accidentally type response.firstName in your React component, TypeScript will not show an error in your IDE. Your app will simply crash in production when it tries to render undefined data.
The Interface Solution
Interfaces allow you to declare the exact shape of an object. When you fetch JSON data, you explicitly cast the result to your interface:
export interface User {
id: number;
email: string;
isActive: boolean;
createdAt?: string; // Optional field
}
// Later in your data fetching logic...
const user = await res.json() as User;
console.log(user.email); // IDE autocompletes perfectly!Handling Deeply Nested Objects
Most APIs return deeply nested structures. Instead of creating one giant interface, you should compose smaller interfaces together.
export interface GeoBlock {
lat: number;
lng: number;
}
export interface Address {
street: string;
city: string;
geo: GeoBlock;
}
export interface Company {
name: string;
catchPhrase: string;
}
export interface UserResponse {
id: number;
name: string;
address: Address;
company: Company;
}Don't Write Boilerplate By Hand
Defining interfaces for a 200-line JSON payload from a third-party API is soul-crushing work. You will inevitably misspell a key, miss an optional property, or incorrectly infer a type (like assuming an ID is a number when it's actually a UUID string).
Instead of hand-coding interfaces, professional developers use tools like the JSON to Model Generator. You paste your raw JSON, and the engine recursively traverses the data tree, identifies data types, separates nested objects, and names your interfaces perfectly.