Rules Hub
Code Ruleset
Rule priority, scope & exceptions
Use this to align rules with the senior-level structure (P0/P1/P2, scope, exceptions/tradeoffs).
Preserve real input/output relationships in generic helpers
Use honest generic relationships and validated transformations; casting through unknown does not make a result safe.
Bad example
| 1 | async function fetchApi<TData, TResult = TData>( |
| 2 | url: string, |
| 3 | transform?: (data: TData) => TResult |
| 4 | ): Promise<TResult> { |
| 5 | const response = await fetch(url); |
| 6 | |
| 7 | // Direct cast forces TData, making it hard to return TResult later |
| 8 | // without ugly double casting (as unknown as TResult). |
| 9 | const data = await response.json() as TData; |
| 10 |
|
| 11 | if (transform) { |
| 12 | return transform(data); |
| 13 | } |
| 14 |
|
| 15 | // TypeScript error: Type 'TData' is not assignable to type 'TResult'. |
| 16 | // 'TResult' could be instantiated with an arbitrary type which could be unrelated to 'TData'. |
| 17 | return data; |
| 18 | } |
Explanation (EN)
An unconstrained TResult can claim a runtime shape that no code created.
Objašnjenje (HR)
Neograničeni TResult može tvrditi oblik koji nikakav izvršeni kod nije proizveo.
Good example
| 1 | async function fetchApi<T>(url: string, parse: (raw: unknown) => T): Promise<T> { |
| 2 | const response = await fetch(url); |
| 3 | if (!response.ok) throw new Error(`Upstream status ${response.status}`); |
| 4 | const raw: unknown = await response.json(); |
| 5 | return parse(raw); |
| 6 | } |
Explanation (EN)
The required parser validates and produces the promised type; callers can compose a typed transformation after parsing.
Objašnjenje (HR)
Obavezni parser validira i proizvodi obećani tip. Pozivatelj nakon parsiranja može dodati tipiziranu transformaciju.
Notes (EN)
Prefer a validated parser plus an explicit transform so the output type follows actual computation, instead of allowing arbitrary independent generic result types.
Exceptions / Tradeoffs (EN)
An intermediate unknown assertion can isolate a proven compiler limitation for trusted data, but it is not a safety check. Never use it to pretend an absent transform produced a different type.