Rules Hub
Coding Rules Library
Rule priority, scope & exceptions
Use this to align rules with the senior-level structure (P0/P1/P2, scope, exceptions/tradeoffs).
Define distinct types for distinct data shapes
Avoid reusing a single type for multiple API responses that have differing structures; create specific types to ensure strict type safety.
Bad example
| 1 | type Webcast = { |
| 2 | id: number; |
| 3 | title: string; |
| 4 | // Fields specific to Endpoint A |
| 5 | webcastId?: string; |
| 6 | millistreamId?: number; |
| 7 | // Fields specific to Endpoint B (added later) |
| 8 | imageUrl?: string; |
| 9 | instrument?: { name: string }; |
| 10 | }; |
| 11 |
|
| 12 | // Consumer doesn't know which fields are guaranteed |
| 13 | function render(item: Webcast) { |
| 14 | return <div>{item.instrument?.name}</div>; |
| 15 | } |
Explanation (EN)
Reusing a single type for different API endpoints forces fields to be optional to accommodate both shapes. This leads to a weak type definition where developers cannot rely on the existence of specific properties without manual checks.
Objašnjenje (HR)
Ponovno korištenje jednog tipa za različite API endpointe prisiljava te da polja označiš kao opcionalna kako bi podržao obje strukture. To dovodi do slabe definicije tipa gdje se programeri ne mogu osloniti na postojanje određenih svojstava bez ručnih provjera.
Good example
| 1 | type WebcastDetail = { |
| 2 | id: number; |
| 3 | title: string; |
| 4 | webcastId: string; |
| 5 | millistreamId: number; |
| 6 | }; |
| 7 |
|
| 8 | type WebcastSummary = { |
| 9 | id: number; |
| 10 | title: string; |
| 11 | imageUrl: string | null; |
| 12 | instrument: { name: string } | null; |
| 13 | }; |
| 14 |
|
| 15 | // Consumer knows exactly what data is available |
| 16 | function render(item: WebcastSummary) { |
| 17 | return <div>{item.instrument?.name}</div>; |
| 18 | } |
Explanation (EN)
Creating distinct types (`WebcastDetail`, `WebcastSummary`) accurately reflects the data returned by each endpoint. This allows TypeScript to enforce strict contracts, ensuring required fields are always present for the specific context.
Objašnjenje (HR)
Kreiranje zasebnih tipova (`WebcastDetail`, `WebcastSummary`) točno odražava podatke koje vraća svaki endpoint. To omogućuje TypeScriptu da nametne stroge ugovore, osiguravajući da su obavezna polja uvijek prisutna za određeni kontekst.