Aller au contenu
Aback Tools Logo

Erreur TypeScript TS1384 : cause et correction

Corrigez l'erreur TypeScript TS1384 (« le modificateur export ne peut pas s'appliquer à une augmentation de module »). Les trois causes, le correctif export {}, isolatedModules et les motifs .d.ts.

DH
Tutorials & How-Tos11 min de lecture2,650 mots

L'erreur TypeScript TS1384 fait partie de ces erreurs qui semblent cryptiques à première vue mais dont la cause est toujours précise et corrigeable. Elle apparaît lorsque le compilateur trouve un modificateur export à un endroit où il ne peut pas légalement figurer, précisément dans un bloc d'augmentation de module. Ce guide explique exactement ce que signifie TS1384, passe en revue chaque scénario qui le déclenche et donne le bon correctif pour chacun.

TS1384Code d'erreurExport dans une augmentation de module
1 ligneCorrectif typiqueexport {} résout la plupart des cas
3Causes racinesScript, isolatedModules, .d.ts

Qu'est-ce que TS1384 ?

L'erreur TypeScript TS1384 porte le message : « le modificateur "export" ne peut pas s'appliquer à une augmentation de module ». Elle apparaît lorsque le compilateur rencontre un mot-clé `export` dans un bloc `declare module` ou `declare global`, les deux constructions que TypeScript utilise pour l'augmentation de module. Les blocs d'augmentation servent à étendre les types de modules existants, pas à déclarer de nouveaux symboles publics : `export` y est donc structurellement invalide.

L'augmentation de module en une phrase

L'augmentation de module est le mécanisme TypeScript qui permet d'ajouter des membres aux types d'un module existant : par exemple ajouter une propriété personnalisée à `Express.Request`, étendre `Window` avec un global tiers ou ajouter des méthodes aux options de composants d'un framework. La syntaxe ressemble à un bloc `declare module 'nom-du-module' {}` et doit se trouver dans un fichier de module (un fichier comportant au moins une instruction `import` ou `export` de premier niveau).

  • TS1384 est une erreur du compilateur : le fichier ne passera pas la vérification de type tant qu'elle n'est pas corrigée
  • Elle n'affecte pas l'exécution : l'erreur ne concerne que les déclarations de type
  • Elle est déterministe : le même code la déclenche toujours, il n'existe pas de version intermittente
  • Ses causes racines sont peu nombreuses : contexte script contre module, isolatedModules et structure .d.ts incorrecte couvrent 95 % des cas

Note

TS1384 est proche de TS2669 (« les augmentations de la portée globale ne peuvent être imbriquées directement que dans des modules externes ou des déclarations de module ambiant ») mais s'en distingue. Les deux proviennent d'un contexte de fichier inadapté à la syntaxe d'augmentation et se corrigent avec la même technique `export {}` ; toutefois TS2669 se déclenche à cause de l'emplacement du bloc `declare global`, tandis que TS1384 se déclenche spécifiquement sur un modificateur `export` dans l'augmentation.

Quand TS1384 se déclenche

L'erreur implique toujours un `export` là où TypeScript ne l'autorise pas. Trois motifs distincts la produisent, et déterminer lequel s'applique à votre base de code détermine le bon correctif.

Motif 1 : export dans un bloc declare module

Le déclencheur le plus direct : vous écrivez une instruction `export` dans une augmentation `declare module`. L'intention est généralement d'ajouter quelque chose à l'API publique du module, mais les blocs d'augmentation ne fonctionnent pas ainsi : ils ne peuvent qu'étendre des déclarations de type déjà présentes dans le module cible.

typescript
// ✗ TS1384 - export dans une augmentation de module
declare module 'some-library' {
  export interface NewInterface {   // <-- TS1384 se déclenche ici
    id: string;
  }
}

// ✓ Correct - interface ajoutée sans export
declare module 'some-library' {
  interface ExistingInterface {
    newProperty: string;            // étend le type existant
  }
}

Motif 2 : le fichier est traité comme un script, pas un module

C'est la cause la plus fréquente de TS1384 dans les vrais projets. Si un fichier ne contient aucune instruction `import` ou `export` de premier niveau, TypeScript le traite comme un script à portée globale. Un bloc `declare global {}` dans un fichier de script n'a pas de sens (les globales sont déjà globales dans un script), donc TypeScript rejette tout `export` qu'il contient avec TS1384. Le fichier doit être un module pour que le contexte d'augmentation ait un sens.

Motif 3 : structure incorrecte du fichier .d.ts

Les fichiers de déclaration (`.d.ts`) qui mélangent déclarations de module ambiant et instructions `export` classiques dans le mauvais ordre peuvent déclencher TS1384. Un `.d.ts` qui commence par des déclarations `export` de premier niveau puis contient un bloc `declare module` est traité comme un module, ce qui est correct. Mais un `.d.ts` qui englobe tout dans un unique bloc `declare module` puis tente d'utiliser `export` dans ce bloc confond le contexte d'augmentation avec un contexte de définition de module.

Warning

TS1384 peut aussi provenir d'un **paquet tiers** qui fournit des fichiers `.d.ts` défectueux. Si l'erreur pointe vers un chemin dans `node_modules`, la source est une dépendance, pas votre code. Dans ce cas, le correctif est `skipLibCheck: true` dans tsconfig.json, pas la modification des fichiers du paquet.

Corriger TS1384 : augmentation de module

Le bon correctif dépend de ce que vous cherchez réellement à accomplir. Deux objectifs différents peuvent mener à TS1384 et demandent des approches différentes. Suivez ces quatre étapes pour résoudre l'erreur proprement.

1

Identifier le motif qui déclenche TS1384

Lisez attentivement l'erreur complète du compilateur. Notez l'extension du fichier (.ts ou .d.ts), le numéro de ligne et si l'`export` se trouve dans un bloc `declare module`, un bloc `declare global` ou ailleurs. Le contexte du code environnant vous indiquera lequel des trois motifs ci-dessus s'applique. Si le chemin de l'erreur commence par `node_modules/`, passez au correctif `skipLibCheck` : les autres motifs ne s'appliquent pas.

2

Ajouter export {} pour convertir le fichier en module

Si votre fichier contient un bloc `declare module` ou `declare global` mais aucun import ou export de premier niveau, ajoutez `export {}` en haut. Cette seule ligne fait passer le fichier d'un contexte de script à un contexte de module, l'environnement requis pour la syntaxe d'augmentation. L'export vide n'ajoute rien au résultat compilé : c'est purement un signal de contexte pour TypeScript.

src/types/global.d.ts
typescript
// Ajoutez cette ligne pour convertir le fichier en module
export {};

declare global {
  interface Window {
    myAnalytics: AnalyticsInstance;
  }
}
3

Déplacer declare global dans un module existant

Une alternative à l'ajout de `export {}` consiste à placer le bloc `declare global` dans un fichier comportant déjà de vrais imports ou exports, comme le point d'entrée d'une bibliothèque, un module de fonctionnalité ou un fichier d'utilitaires partagés. Cette approche garde vos augmentations de type à côté du code qu'elles étendent, ce qui peut être plus facile à maintenir qu'un fichier de déclarations globales dédié.

4

Supprimer export à l'intérieur du bloc d'augmentation

Si vous voulez réellement ajouter un nouveau type exportable à l'API publique d'un module existant, le bloc d'augmentation n'est pas le bon endroit. Déplacez la déclaration entièrement en dehors du bloc `declare module`. Pour augmenter une interface existante, utilisez le même nom d'interface sans `export` dans le bloc : TypeScript la fusionne automatiquement via la fusion de déclarations.

Formateur et validateur JSON

Validez votre tsconfig.json et votre package.json pour détecter les erreurs de syntaxe instantanément dans votre navigateur, sans compilateur TypeScript.

Open tool

TS1384 et isolatedModules

L'option de compilateur `isolatedModules` est activée par défaut dans Vite, Next.js, Create React App avec Babel et tout projet utilisant esbuild ou SWC. Elle exige que chaque fichier soit transformable indépendamment, sans information de type inter-fichiers, ce qui ajoute des contraintes qui amplifient plusieurs erreurs TypeScript, dont TS1384.

Ce que restreint isolatedModules

ConstructionSans isolatedModulesAvec isolatedModules
`const enum`✓ Autorisé partout✗ Uniquement dans les .d.ts
`export type`✓ Facultatif✓ Obligatoire pour réexporter des types
`import type`✓ Facultatif✓ Obligatoire pour importer des types
Déclarations ambiantes✓ Dans tout fichier .ts✓ Préférable dans un .d.ts
Augmentation de module✓ Dans un .ts module✓ Préférable dans un .d.ts
Réexport d'espaces de noms✓ Autorisé✗ Restreint

Le correctif propre à isolatedModules

Quand `isolatedModules` est actif et que TS1384 apparaît sur une augmentation dans un fichier `.ts` classique, le correctif le plus propre est de déplacer l'augmentation dans un fichier `.d.ts`. Les fichiers de déclaration ne sont jamais transformés par esbuild ou Babel : seul le compilateur TypeScript les lit. Cela élimine complètement la contrainte isolatedModules pour cette augmentation.

src/types/express.d.ts
typescript
// Ce motif fonctionne correctement avec isolatedModules
export {};

declare module 'express' {
  interface Request {
    userId?: string;
    tenantId?: string;
  }
}

Tip

Si vous ne savez pas si `isolatedModules` est activé dans votre projet, cherchez `"isolatedModules": true` dans votre tsconfig.json. Vous pouvez aussi consulter la configuration de votre bundler : le modèle tsconfig par défaut de Vite l'inclut et Next.js l'active automatiquement avec SWC. Utilisez le [Comparateur de différences](/tools/data/dev-utilities/diff-viewer) pour comparer votre tsconfig à une référence connue lors du diagnostic de problèmes TS1384 propres à un environnement.

TS1384 dans les fichiers .d.ts

Les fichiers de déclaration ajoutent leurs propres nuances à TS1384. Les règles sur ce qui est valide dans un fichier `.d.ts` diffèrent légèrement de celles des fichiers `.ts` classiques, et les motifs qui produisent TS1384 dans les fichiers de déclaration sont souvent moins intuitifs.

Définition de module ambiant ou augmentation ?

Un fichier `.d.ts` peut contenir deux choses fondamentalement différentes qui se ressemblent mais se comportent autrement. Une définition de module ambiant (`declare module 'nom' {}` dans un `.d.ts` en contexte de script, sans import ni export) définit de zéro tous les types d'un module : elle sert à typer des bibliothèques JavaScript non typées. Une augmentation de module (`declare module 'nom' {}` dans un `.d.ts` en contexte de module avec un `export {}`) étend les types d'un module existant. La distinction est importante car `export` est valide dans une définition de module ambiant mais produit TS1384 dans une augmentation de module.

Choisir le bon motif .d.ts

Si votre fichier `.d.ts` définit les types d'une bibliothèque non typée (par exemple typer un ancien plugin jQuery), gardez-le en contexte de script sans `export {}` en tête. Utilisez `export` librement dans le bloc `declare module`. Si votre fichier `.d.ts` augmente une bibliothèque déjà typée (par exemple ajouter une propriété à `Express.Request`), ajoutez `export {}` en haut et retirez tout `export` du bloc `declare module`.

Note

Un moyen rapide de déterminer le motif applicable : si le module visé possède déjà des définitions de type (via `@types/...` ou intégrées), vous faites une augmentation. S'il n'a aucun type et que vous les créez de zéro, vous écrivez une définition de module ambiant.

skipLibCheck en dernier recours

Quand TS1384 apparaît sur un chemin dans `node_modules` et que vous n'avez aucun contrôle sur le paquet, ajoutez `"skipLibCheck": true` à votre tsconfig.json. Cela indique à TypeScript d'ignorer la vérification de type de tous les fichiers `.d.ts`, y compris ceux de `node_modules`. C'est une option de configuration légitime et très répandue, pas un bricolage. La contrepartie est que vous perdez entièrement la vérification de type des déclarations de bibliothèques : des types réellement défectueux dans les dépendances passeront inaperçus. N'utilisez `skipLibCheck` que lorsque l'alternative est de bloquer votre build.

TS1384 dans les frameworks et bundlers

Chaque framework et outil de build configure TypeScript différemment, ce qui signifie que TS1384 peut apparaître pour des raisons légèrement différentes selon votre stack. Voici comment les environnements les plus courants produisent et résolvent l'erreur.

Next.js

Next.js active `isolatedModules` automatiquement via son tsconfig par défaut et utilise SWC pour la transformation. Le motif standard d'augmentation de types dans Next.js est un répertoire `types/` dédié à la racine du projet, contenant des fichiers `.d.ts` commençant par `export {}`. Next.js génère aussi un fichier `next-env.d.ts` : ne l'éditez jamais à la main, car il est régénéré à chaque build et vos modifications seront perdues. Ajoutez vos augmentations dans un fichier séparé.

Vite

Les projets Vite utilisent esbuild pour la transformation et incluent `isolatedModules: true` dans le tsconfig par défaut. Vite génère également un fichier `vite-env.d.ts` pour ses propres globales. Ajoutez les augmentations de module dans un répertoire `src/types/` séparé. Le motif `export {}` résout TS1384 dans toutes les configurations Vite standard, et conserver les augmentations dans des fichiers `.d.ts` reste l'approche la plus sûre lorsque la transformation esbuild est dans la chaîne.

API Node.js / Express simples

Les projets Express augmentent souvent `Express.Request` pour ajouter la session utilisateur ou le contexte d'authentification. Le motif canonique est un fichier `src/types/express/index.d.ts` commençant par `export {}` suivi de l'augmentation `declare module 'express-serve-static-core'`. Sans `isolatedModules`, cela fonctionne aussi dans un fichier `.ts` classique, mais utiliser `.d.ts` reste la convention la plus propre dans tous les cas. Vérifiez toujours le nom exact du module dans les définitions de type d'Express : la cible de l'augmentation est `express-serve-static-core`, pas `express`.

Le fichier doit être un module avant de pouvoir en augmenter un. Un seul `export {}` transforme un script en module et débloque tout le système d'augmentation.

- Principe d'augmentation de module TypeScript

Éviter TS1384 sur le long terme

TS1384 s'introduit facilement par accident, surtout quand de nouveaux membres de l'équipe ajoutent des augmentations de type ou quand vous migrez un projet vers un nouveau bundler. Ces pratiques l'empêchent de revenir après l'avoir corrigé.

Établir une convention de répertoire de types

Créez un répertoire `src/types/` (ou `types/`) et conservez-y toutes les augmentations de module sous forme de fichiers `.d.ts`. Chaque fichier doit contenir une augmentation et commencer par `export {}`. Documentez cette convention dans le `CONTRIBUTING.md` du projet pour que les nouveaux contributeurs sachent où placer les déclarations de type. Un emplacement cohérent facilite aussi l'audit des augmentations lors des mises à jour de dépendances.

Utiliser tsc --noEmit en CI

Exécuter `tsc --noEmit` comme étape de CI détecte TS1384 (et toute autre erreur TypeScript) avant que le code n'atteigne main. Beaucoup de projets sautent la vérification de type en CI parce que leur bundler ne l'exige pas : esbuild et SWC suppriment les types sans les vérifier. Ajoutez `tsc --noEmit` comme étape distincte pour que les erreurs de type, dont TS1384, soient détectées à chaque pull request.

Auditer les changements de tsconfig avec le comparateur de différences

Les modifications de tsconfig.json (ajout de `isolatedModules`, changement de `moduleResolution`, mise à jour de `lib`) peuvent introduire TS1384 dans des fichiers qui compilaient auparavant sans erreur. Quand un changement de tsconfig arrive, utilisez le Comparateur de différences pour comparer l'ancienne et la nouvelle configuration côte à côte. Vous voyez immédiatement quelles options ont changé et pouvez relier les nouveaux TS1384 au réglage précis qui les a causés.

Tip

Après avoir corrigé TS1384, validez la syntaxe de votre tsconfig.json avec le [Formateur et validateur JSON](/tools/data/formatters/json-formatter-viewer) : les fichiers tsconfig sont du JSON, et une virgule finale ou un guillemet manquant empêchera silencieusement TypeScript de lire le changement de configuration que vous venez de faire.

Comparateur de différences

Comparez deux versions de tsconfig.json, package.json ou de tout fichier texte côte à côte pour voir exactement ce qui a changé, dans le navigateur et sans rien téléverser.

Open tool

Key takeaways

  • TS1384 apparaît quand un modificateur `export` se trouve dans un bloc d'augmentation `declare module` ou `declare global` ; le correctif tient presque toujours en une ligne.
  • Cause la plus fréquente : le fichier n'a ni import ni export, TypeScript le traite donc comme un script. Ajoutez `export {}` en tête pour le convertir en module.
  • Avec `isolatedModules: true` (projets Vite, Next.js, esbuild), déplacez les augmentations dans des fichiers `.d.ts` : exclus de la transformation, ils évitent complètement la contrainte.
  • Si TS1384 pointe vers un chemin dans `node_modules`, le correctif est `skipLibCheck: true` dans tsconfig.json : vous ne pouvez pas modifier les déclarations d'une dépendance.
  • Définitions de module ambiant (typer une bibliothèque non typée) et augmentations de module (étendre une bibliothèque typée) se ressemblent mais diffèrent : `export` dans le bloc n'est valide que dans les définitions, pas dans les augmentations.
  • Ajoutez `tsc --noEmit` à votre pipeline CI pour détecter TS1384 à chaque pull request, même si votre bundler (esbuild, SWC) ne vérifie pas les types pendant le build.
  • Validez la syntaxe de tsconfig.json avec le Formateur et validateur JSON après chaque changement : une erreur de syntaxe JSON empêche silencieusement TypeScript de lire votre configuration.

Questions fréquentes

TS1384 signifie que TypeScript a rencontré un modificateur `export` à un endroit où il n'est pas autorisé, précisément à l'intérieur d'un bloc d'augmentation de module. Le message complet est : « le modificateur "export" ne peut pas s'appliquer à une augmentation de module ». Les augmentations de module étendent des types existants avec `declare module '...' {}` ou `declare global {}`. Elles ne peuvent pas exporter de nouveaux symboles : elles ajoutent seulement des déclarations à un module qui existe déjà. Tout `export` à l'intérieur du bloc d'augmentation déclenche TS1384.

Le correctif le plus fréquent consiste à s'assurer que le fichier est un module et non un script. Ajoutez `export {}` en haut si le fichier ne contient ni import ni export. Cela le fait passer d'un contexte de script à un contexte de module, ce que TypeScript exige pour la syntaxe d'augmentation `declare module` et `declare global`. Si vous voulez ajouter de nouveaux types plutôt qu'augmenter des types existants, déplacez les déclarations de type en dehors du bloc `declare module`.

Le bloc `declare global {}` doit se trouver dans un fichier que TypeScript considère déjà comme un module, c'est-à-dire comportant au moins un `import` ou un `export` de premier niveau. Sans cela, TypeScript traite le fichier comme un script, et `declare global` dans un script produit TS1384. Ajoutez `export {}` à la fin du fichier pour forcer le mode module sans exporter quoi que ce soit. C'est le motif standard pour les fichiers d'augmentation de types globaux.

Un fichier TypeScript est un script s'il ne contient aucune instruction `import` ou `export` de premier niveau : les déclarations des scripts partagent une portée globale visible par tous les autres fichiers de script. Un fichier comportant au moins un `import` ou un `export` est un module doté de sa propre portée isolée. La syntaxe d'augmentation de module n'est autorisée que dans les fichiers de module. Ajouter `export {}`, un export vide, transforme un script en module et résout TS1384 sans modifier le comportement à l'exécution.

Oui, dans certains cas précis. Avec `isolatedModules: true` dans tsconfig.json, TypeScript exige que chaque fichier puisse être transformé indépendamment. Les augmentations de types uniquement dans des fichiers .ts classiques peuvent déclencher TS1384 lorsque esbuild ou Babel tentent de les traiter, car ces outils ne peuvent pas résoudre les informations de type entre fichiers. Déplacer l'augmentation dans un fichier .d.ts résout le problème : les fichiers de déclaration sont exclus de la transformation par tous les bundlers majeurs.

Oui. Si un paquet fournit des déclarations de type incorrectes utilisant `export` à l'intérieur d'un bloc d'augmentation de module, votre projet émet TS1384 quand TypeScript lit ces déclarations. Le correctif pragmatique consiste à ajouter `skipLibCheck: true` à votre tsconfig.json, ce qui ignore la vérification de type des fichiers de déclaration dans node_modules. C'est un contournement : la vraie solution est que l'auteur du paquet corrige ses déclarations. Envisagez d'ouvrir un ticket sur le dépôt du paquet avec le contexte TS1384 précis.

TS2669 (« les augmentations de la portée globale ne peuvent être imbriquées directement que dans des modules externes ou des déclarations de module ambiant ») est étroitement liée. Les deux erreurs apparaissent lorsque le contexte du fichier ne convient pas à une augmentation de module. TS1384 se produit quand un modificateur `export` apparaît à l'intérieur même du bloc d'augmentation ; TS2669 se produit quand un bloc `declare global {}` se trouve dans un fichier de script plutôt que dans un module. Le correctif est identique pour les deux : ajoutez au moins une instruction `import` ou `export` au fichier.

Exécutez `tsc --noEmit` depuis la racine de votre projet : TypeScript valide le tsconfig.json et signale les erreurs de configuration sans générer de fichiers de sortie. Pour les erreurs de syntaxe JSON dans le tsconfig.json lui-même (virgule manquante, virgule finale, nom de propriété erroné), collez le contenu du fichier dans le Formateur et validateur JSON d'Aback Tools, qui met en évidence les problèmes de syntaxe instantanément dans votre navigateur, sans avoir besoin du compilateur TypeScript.

ShareXLinkedIn