ProgrammationDéveloppeur Frontend

Comment fonctionne le mécanisme de typage des modules JavaScript importés dans TypeScript ? Comment typiser un import si le fichier JS source ne contient pas de types ? Quels sont les nuances et les risques du travail avec any lors de l'importation ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

Historique de la question :

TypeScript est destiné à ajouter un typage statique aux applications JS existantes. La question se pose : comment typiser un import lorsque l'on connecte un module tiers ou un module personnalisé écrit en JavaScript pur, où il n'y a pas de types ? Dans ce cas, TypeScript utilise ce que l'on appelle des fichiers de déclaration (.d.ts), ou en déduit les types automatiquement (parfois de manière incorrecte).

Problème :

Si lors de l'importation, TypeScript ne trouve pas de description de type appropriée, la variable acquiert le type any, ce qui signifie une perte totale de sécurité de type. Cela peut entraîner des erreurs que le compilateur ne remarquera pas et des bugs à l'exécution. Souvent, les développeurs oublient de déclarer explicitement les types pour les fonctions/objets importés.

Solution :

  1. Pour vos modules JS, vous pouvez écrire des déclarations de types manuellement (fichiers .d.ts).
  2. Pour les bibliothèques populaires, il existe souvent des paquets @types/.
  3. Vous pouvez déclarer des types en importation explicitement, en décrivant vous-même la structure de l'objet requis.
  4. Il est recommandé d'éviter any, et si ce n'est pas possible, de limiter au minimum la portée d'utilisation.

Exemple de code :

// 1. Typage explicite de l'import d'un module JS import myFunc from './myLib'; declare function myFunc(x: number): boolean; // 2. Import depuis un module JS, pour lequel un fichier myLib.d.ts a été créé avec export function myFunc(x: number): boolean; import { myFunc } from './myLib'; // 3. Import d'un module sans typage et description explicite du type import * as legacy from './legacy'; const typedLegacy: { runTask: (name: string) => void } = legacy;

Caractéristiques clés :

  • En l'absence de déclarations, la valeur importée obtient par défaut le type any, ce qui viole la sécurité de type.
  • La meilleure approche est de créer des fichiers .d.ts pour les modules tiers/vos bibliothèques.
  • Si nécessaire, il est possible de déclarer localement des fonctions/modules externes via declare/interfaces.

Questions pièges.

TypeScript peut-il déduire automatiquement les types d'un module JS importé sans déclarations ?

Non, si le fichier est écrit en JavaScript, sans déclarations de types, TypeScript est contraint de supposer any et perd les informations sur les types, sauf dans des cas triviaux (export const x = 1;).

Peut-on "étendre" les types importés si de nouveaux champs apparaissent dans le module JS ?

Seulement si vous mettez à jour le fichier de déclaration (.d.ts). Si les types sont fixés dans .d.ts, TypeScript les utilisera comme "vérité", tout nouveau champ restera non typé ou entraînera une erreur.

Est-il sûr d'importer un module JS tiers dans un projet TypeScript s'il n'y a pas de @types/ et de déclarations ?

Non, cela réduit considérablement la sécurité - tout le travail avec l'import est non typé (any), le compilateur ne signalera pas d'erreurs, même si le module est inaccessible ou si l'API a changé. Travailler avec de tels modules n'est acceptable que comme solution temporaire, avec typage explicite ou isolement du code.

Erreurs de typage et anti-patrons

  • Oublier les déclarations (.d.ts) pour les paquets tiers.
  • Faire confiance aveuglément à any implicite lors de l'importation de modules JS.
  • Violer les limites du code type-safe.

Exemple de la vie réelle

Cas négatif

Un développeur importe une bibliothèque JS tierce sans déclarations, utilise l'API en toute confiance, obtenant le type any. Après la mise à jour de la bibliothèque, la signature des méthodes change, mais aucune erreur ne se produit, seulement des bugs à l'exécution.

Avantages :

  • Connexion rapide et simple à n'importe quel module JS.

Inconvénients :

  • Pas de garanties de sécurité de type, les erreurs restent indétectables jusqu'à l'exécution.

Cas positif

Un fichier de déclaration .d.ts est créé ou un paquet @types/ est ajouté, décrivant l'API strictement conforme au module JS d'origine. Tous les méthodes importées sont typées, l'IDE suggère l'auto-complétion, toutes les incohérences montrent une erreur de compilation.

Avantages :

  • Sécurité de type, avertissement des erreurs avant l'exécution.
  • Support de l'auto-complétion et documentation directement dans le code.

Inconvénients :

  • Nécessite du temps pour écrire .d.ts, support des types lors des mises à jour du module JS.