Meilleures pratiques TypeScript pour les développeurs
TypeScript est devenu le langage de choix pour les développeurs web professionnels qui construisent des applications à grande échelle. Dans cet article, je partagerai quelques bonnes pratiques que j'ai apprises et qui peuvent vous aider à écrire un code plus maintenable et robuste.
Utiliser la vérification stricte des types
Activez toujours la vérification stricte des types dans votre tsconfig.json
. Cela détecte plus d'erreurs potentielles et vous oblige à être explicite sur vos types.
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictBindCallApply": true
}
}
Tirer parti de l'inférence de type
L'inférence de type de TypeScript est puissante. Utilisez-la à votre avantage pour réduire la verbosité tout en maintenant la sécurité des types.
// Au lieu de ceci :
const numbers: number[] = [1, 2, 3].map((num: number): number => num * 2);
// Faites ceci :
const numbers = [1, 2, 3].map(num => num * 2);
Utiliser des unions discriminées pour les états complexes
Lorsque vous traitez un état complexe qui peut prendre différentes formes, utilisez des unions discriminées pour rendre votre code plus sûr au niveau des types.
type LoadingState = {
status: 'loading';
};
type SuccessState = {
status: 'success';
data: any;
};
type ErrorState = {
status: 'error';
error: Error;
};
type State = LoadingState | SuccessState | ErrorState;
function handleState(state: State) {
switch (state.status) {
case 'loading':
// TypeScript sait que c'est un LoadingState
return <LoadingSpinner />;
case 'success':
// TypeScript sait que c'est un SuccessState et que state.data existe
return <DataView data={state.data} />;
case 'error':
// TypeScript sait que c'est un ErrorState et que state.error existe
return <ErrorMessage error={state.error} />;
}
}
Utiliser des types utilitaires
TypeScript fournit de nombreux types utilitaires qui peuvent vous aider à créer des types complexes sans répétition.
interface User {
id: string;
name: string;
email: string;
age: number;
}
// Rend toutes les propriétés optionnelles
type PartialUser = Partial<User>;
// Rend toutes les propriétés en lecture seule
type ReadonlyUser = Readonly<User>;
// Sélectionne un sous-ensemble de propriétés
type UserCredentials = Pick<User, 'email' | 'id'>;
// Omet certaines propriétés
type UserWithoutId = Omit<User, 'id'>;
Éviter l'utilisation de any
L'utilisation de any
contourne le système de typage de TypeScript. Évitez-le autant que possible.
// Au lieu de ceci :
function processData(data: any) {
return data.map(item => item.value);
}
// Faites ceci :
interface DataItem {
value: string;
// autres propriétés...
}
function processData(data: DataItem[]) {
return data.map(item => item.value);
}
Utiliser des interfaces pour les objets publics et des types pour les unions
Une bonne règle générale est d'utiliser des interfaces pour les API publiques et des types pour les unions et les types utilitaires.
// Interface pour une API publique
interface User {
id: string;
name: string;
}
// Type pour une union
type NotificationStatus = 'info' | 'warning' | 'error';
Tirer parti des génériques
Les génériques vous permettent de créer des composants réutilisables qui fonctionnent avec différents types tout en maintenant la sécurité des types.
// Une fonction générique simple
function identity<T>(arg: T): T {
return arg;
}
// Un composant React générique
function List<T>({ items, renderItem }: { items: T[]; renderItem: (item: T) => React.ReactNode }) {
return <ul>{items.map((item, index) => <li key={index}>{renderItem(item)}</li>)}</ul>;
}
Conclusion
L'adoption de ces meilleures pratiques TypeScript peut considérablement améliorer la qualité et la maintenabilité de votre code. En tirant pleinement parti du système de types de TypeScript, vous pouvez attraper les erreurs plus tôt dans le cycle de développement et créer des applications plus robustes.
Quelles sont vos meilleures pratiques TypeScript préférées ? Partagez-les dans les commentaires ci-dessous !