๐๐ผ๐ ๐๐ผ ๐ง๐๐ฝ๐ฒ ๐๐ฃ๐ ๐ฅ๐ฒ๐๐ฝ๐ผ๐ป๐๐ฒ๐ ๐ถ๐ป ๐ง๐๐ฝ๐ฒ๐ฆ๐ฐ๐ฟ๐ถ๐ฝ๐
TypeScript checks your code. It does not check your data.
You might turn on strict mode and fix every error. You feel safe. Then a third-party API changes a number to a string. Your app crashes in production. TypeScript said nothing.
This happens because TypeScript is a build-time tool. Once data crosses the network, your types are just promises. No one enforces them at runtime.
Stop using type assertions.
When you use "as User", you tell the compiler to trust you. You are not verifying anything. If the API returns a null value where you expect a string, your app will fail. You are silencing the compiler instead of fixing the problem.
The right way to handle data:
โข Use generics for better code. A wrapper function like getJson
โข Validate at the boundary. This is the most important step. Use a schema library like Zod. You write a schema once. You then derive your TypeScript types from that schema.
โข Use "unknown" instead of "any". When you fetch data, treat it as unknown first. This forces you to prove the data is correct before you use it.
โข Use Zod's parse method. This inspects the data as it enters your app. If the data is wrong, it throws an error immediately at the edge. You catch the mistake before it reaches your business logic.
โข Use code generation for existing contracts. If an API has OpenAPI or GraphQL, generate your types from it. This keeps your types tied to the actual API spec.
Summary for your workflow:
- For internal APIs you control: A generic wrapper is fine for speed.
- For third-party data: Use schema validation like Zod. This is the safest path.
- For APIs with specs: Generate types from the contract and add runtime checks.
Do not let your types lie to you. Verify your data at the door.