Rules Hub
Coding Rules Library
Infer loader data types from implementation
Avoid manually defining loader return types; infer them directly from the loader function using TypeScript.
Bad example
| 1 | import { useLoaderData } from 'react-router'; |
| 2 |
|
| 3 | // ❌ Manual type definition requires double maintenance |
| 4 | interface LoaderData { |
| 5 | user: { id: string; name: string }; |
| 6 | timestamp: string; |
| 7 | } |
| 8 |
|
| 9 | export const loader = async () => { |
| 10 | return { |
| 11 | user: { id: '1', name: 'Alice' }, |
| 12 | timestamp: new Date().toISOString(), |
| 13 | }; |
| 14 | }; |
| 15 |
|
| 16 | export default function UserProfile() { |
| 17 | // If loader changes, this type might be wrong |
| 18 | const data = useLoaderData<LoaderData>(); |
| 19 | return <div>{data.user.name}</div>; |
| 20 | } |
Explanation (EN)
Manually defining the `LoaderData` interface creates a maintenance burden. If the `loader` function implementation changes (e.g., adding a field), the type must be manually updated, leading to potential desynchronization and bugs.
Objašnjenje (HR)
Ručno definiranje sučelja `LoaderData` stvara teret održavanja. Ako se implementacija funkcije `loader` promijeni (npr. dodavanje polja), tip se mora ručno ažurirati, što dovodi do potencijalne desinkronizacije i grešaka.
Good example
| 1 | import { useLoaderData } from 'react-router'; |
| 2 |
|
| 3 | export const loader = async () => { |
| 4 | return { |
| 5 | user: { id: '1', name: 'Alice' }, |
| 6 | timestamp: new Date().toISOString(), |
| 7 | }; |
| 8 | }; |
| 9 |
|
| 10 | export default function UserProfile() { |
| 11 | // ✅ Automatically implies the return type of the loader function |
| 12 | const data = useLoaderData<typeof loader>(); |
| 13 | return <div>{data.user.name}</div>; |
| 14 | } |
Explanation (EN)
Using `typeof loader` leverages TypeScript inference to automatically determine the return type. This ensures the component props are always in sync with the actual data returned by the backend logic without extra boilerplate.
Objašnjenje (HR)
Korištenje `typeof loader` iskorištava TypeScript inferenciju za automatsko određivanje povratnog tipa. To osigurava da su propovi komponente uvijek sinkronizirani sa stvarnim podacima koje vraća backend logika, bez dodatnog koda.
Notes (EN)
This also applies to `useRouteLoaderData` where you should import the loader from the parent route and use `typeof importedLoader` instead of recreating the type locally.
Bilješke (HR)
Ovo se također odnosi na `useRouteLoaderData` gdje biste trebali importirati loader iz roditeljske rute i koristiti `typeof importedLoader` umjesto ponovnog kreiranja tipa lokalno.