๐๐ผ๐ ๐๐ผ ๐ง๐๐ฝ๐ฒ ๐๐ฃ๐ ๐ฅ๐ฒ๐๐ฝ๐ผ๐ป๐๐ฒ๐ ๐ถ๐ป ๐ง๐๐ฝ๐ฒ๐ฆ๐ฐ๐ฟ๐ถ๐ฝ๐
TypeScript checks your code. It does not check the data you receive at runtime.
If a third-party API changes a number to a string, your app will crash. TypeScript will not warn you. This happens because your types are just a promise. No one enforces that promise once data crosses the network.
The Problem with Fetch
The fetch function returns data as any. Using any turns off type checking. You can access properties that do not exist. This leads to runtime crashes.
The Danger of Type Assertions
You might use the as keyword to tell the compiler to trust you.
const user = (await response.json()) as User;
This makes your editor happy. It provides autocomplete. But it does not verify the data. If the API returns a null value where you expect a string, your app fails in production. An assertion silences the compiler instead of fixing the problem.
A Better Way: Schema Validation
To fix this, you must check the data at the edge of your app. Use a library like Zod to create a schema.
A schema acts as your single source of truth. You write the schema once and derive your TypeScript type from it.
- Start with unknown: Use the unknown type for incoming JSON. This forces you to verify the data before use.
- Parse the data: Use your schema to inspect the payload.
- Catch errors early: If the data is wrong, the validator throws an error at the boundary. You find the bug immediately.
When to use different methods:
- Internal APIs: A generic wrapper with hand-written interfaces works if you need speed and trust the source.
- Third-party APIs: Use schema validation like Zod. This is the safest choice for important data.
- OpenAPI or GraphQL: Generate types from the contract. Add a runtime check if the source is untrusted.
Stop lying to your compiler. Verify your data at the boundary.