Rules Hub
Code Ruleset
Rule priority, scope & exceptions
Use this to align rules with the senior-level structure (P0/P1/P2, scope, exceptions/tradeoffs).
Define stable return contracts for shared hooks
Use explicit return types for stable shared hook contracts; local inference and project-specific naming remain valid.
Bad example
| 1 | export function useUserProfile(userId: string) { |
| 2 | const [user, setUser] = useState<User | null>(null); |
| 3 | const [loading, setLoading] = useState(true); |
| 4 |
|
| 5 | // Implicit return type inferred by TypeScript |
| 6 | return { user, loading }; |
| 7 | } |
Explanation (EN)
An inferred public return type may change accidentally when implementation details change.
Objašnjenje (HR)
Izvedeni javni povratni tip može se nenamjerno promijeniti promjenom detalja implementacije.
Good example
| 1 | export interface UseUserProfilePayload { |
| 2 | user: User | null; |
| 3 | loading: boolean; |
| 4 | } |
| 5 |
|
| 6 | export function useUserProfile(userId: string): UseUserProfilePayload { |
| 7 | const [user, setUser] = useState<User | null>(null); |
| 8 | const [loading, setLoading] = useState(true); |
| 9 |
|
| 10 | return { user, loading }; |
| 11 | } |
Explanation (EN)
An explicit interface defines a clear contract for the hook. The `Payload` suffix follows a standard naming convention, improving readability and helping IDEs provide better autocompletion.
Objašnjenje (HR)
Eksplicitno sučelje definira jasan ugovor za hook. Sufiks `Payload` prati standardnu konvenciju imenovanja, poboljšava čitljivost i pomaže IDE-u u pružanju boljeg autocompletiona.
Notes (EN)
Declare a stable return contract for shared/public hooks where it prevents accidental API drift; use existing naming conventions and keep exported types useful to consumers.
Exceptions / Tradeoffs (EN)
Local implementation hooks can rely on inference. Do not force a Payload suffix where another project convention is established.