Back

TypeScript dans Node : Configuration pratique

TypeScript dans Node : Configuration pratique

Vous écrivez déjà du TypeScript pour le navigateur. Maintenant, vous en avez besoin côté serveur—pour une API, un script de build ou du SSR. Le problème : la plupart des guides de configuration sont obsolètes et recommandent des configurations CommonJS ou des outils qui ne correspondent pas au Node.js moderne.

Ce guide couvre deux approches pour votre configuration TypeScript Node.js : compiler avec tsc et exécuter du JavaScript, ou exécuter directement des fichiers .ts avec la suppression native des types de Node. Les deux fonctionnent. Chacune convient à des scénarios différents.

Points clés à retenir

  • Définissez "type": "module" dans package.json pour activer ESM par défaut dans les projets TypeScript Node.js modernes
  • Utilisez la compilation tsc pour les déploiements en production, les packages publiés et le code utilisant des enums, namespaces ou parameter properties
  • Utilisez la suppression native des types de Node pour les scripts locaux, les serveurs de développement et les prototypes rapides
  • Utilisez toujours import type pour les imports de types uniquement afin d’éviter les erreurs d’exécution avec la suppression de types
  • Exécutez tsc --noEmit en CI car la suppression de types de Node n’effectue pas de vérification de types

La base : Node 24 LTS et ESM

Commencez avec cette fondation :

{
  "type": "module"
}

Cela active ESM par défaut. Vos imports utilisent la syntaxe ESM, et Node résout les modules en conséquence.

Node 24 est la version LTS de référence actuelle pour cette configuration (téléchargeable ici : https://nodejs.org/en/download).

Approche 1 : Compiler avec tsc, exécuter du JavaScript

Cette approche sépare la compilation de l’exécution. Utilisez-la pour les déploiements en production, les packages publiés ou lorsque vous avez besoin du support complet des fonctionnalités TypeScript.

tsconfig pour Node 24

{
  "compilerOptions": {
    "target": "ES2024",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "rootDir": "src",
    "outDir": "dist",
    "strict": true,
    "skipLibCheck": true,
    "declaration": true,
    "sourceMap": true,
    "verbatimModuleSyntax": true,
    "isolatedModules": true,
    "lib": ["ES2024"]
  },
  "include": ["src"],
  "exclude": ["node_modules", "dist"]
}

Paramètres clés dans cette configuration :

  • module: NodeNext et moduleResolution: NodeNext : Correspond au comportement réel de résolution de modules de Node
  • verbatimModuleSyntax : Nécessite un import type explicite pour les imports de types uniquement—critique pour éviter les erreurs d’exécution (voir la documentation TypeScript : https://www.typescriptlang.org/tsconfig#verbatimModuleSyntax)
  • isolatedModules : Assure la compatibilité avec les outils de transpilation de fichiers uniques

Scripts

{
  "scripts": {
    "build": "tsc",
    "start": "node dist/index.js",
    "dev": "tsc --watch"
  }
}

Exécutez npm run build, puis npm start. Le JavaScript compilé se trouve dans dist/.

Approche 2 : TypeScript natif de Node (suppression de types)

Node a introduit le support natif de TypeScript dans Node 22 et l’a stabilisé dans Node 24 LTS via la suppression de types. Utilisez-le pour les scripts, l’outillage local ou le développement lorsque vous voulez zéro étape de build.

Documentation officielle : https://nodejs.org/api/typescript.html

Comment ça fonctionne

Dans Node 24+, exécutez directement :

node src/index.ts

(Les anciennes versions de Node nécessitaient des flags expérimentaux ; Node 24 n’en a pas besoin.)

Limitations critiques

Le TypeScript natif de Node supprime uniquement les types—il ne vérifie pas les types. Vous avez toujours besoin de tsc --noEmit en CI ou dans votre éditeur pour détecter les erreurs.

Autres contraintes :

  • Ignore tsconfig.json : Node ne lit pas vos options de compilation
  • Nécessite des extensions de fichiers explicites : Écrivez import { foo } from './utils.js' même lorsque le fichier source est utils.ts
  • Respecte les règles ESM vs CJS : Le champ type de votre package.json est important
  • N’exécutera pas le TypeScript depuis node_modules : Les dépendances doivent être du JavaScript compilé
  • Supporte uniquement la syntaxe effaçable : Les enums, namespaces et parameter properties échouent sauf si vous activez --experimental-transform-types

Les extensions de fichiers sont importantes

Pour les formats de modules mixtes :

  • Fichiers .mts → toujours ESM
  • Fichiers .cts → toujours CommonJS
  • Fichiers .ts → suivent le champ type de package.json

Éviter les erreurs d’exécution

Utilisez import type pour les imports de types uniquement :

// Correct
import type { Request, Response } from 'express'
import express from 'express'

// Incorrect - échouera à l'exécution avec la suppression de types
import { Request, Response } from 'express'

Activez verbatimModuleSyntax dans votre tsconfig pour détecter ces problèmes pendant le développement, même si Node ignore la configuration à l’exécution.

Quelle approche utiliser

Utilisez la compilation tsc pour :

  • Les déploiements en production
  • Les packages npm publiés
  • Le code utilisant des enums, namespaces ou parameter properties
  • Les projets nécessitant des source maps en production

Utilisez la suppression native de types pour :

  • Les scripts locaux et l’outillage
  • Les serveurs de développement (associés avec --watch)
  • Les prototypes rapides
  • Les builds de développement SSR

Une configuration de développement pratique

Combinez les deux approches :

{
  "scripts": {
    "dev": "node --watch src/index.ts",
    "typecheck": "tsc --noEmit",
    "build": "tsc",
    "start": "node dist/index.js"
  }
}

Le développement utilise l’exécution native pour la rapidité. La CI exécute typecheck. La production déploie du JavaScript compilé.

Conclusion

La configuration moderne de TypeScript Node.js est plus simple que ne le suggèrent les anciens guides. Utilisez ESM, configurez la résolution de modules NodeNext, et choisissez votre stratégie d’exécution en fonction du contexte. La suppression native de types fonctionne pour le développement et les scripts. La sortie compilée fonctionne pour la production et les packages. Les deux approches partagent le même code source et tsconfig—vous n’êtes pas enfermé dans l’une ou l’autre.

FAQ

La résolution de modules de Node nécessite des extensions de fichiers explicites pour ESM. Lorsque vous écrivez import from ./utils.js, Node recherche ce chemin exact à l'exécution, même si votre fichier source est utils.ts. Puisque la suppression de types retire les types mais ne renomme pas les fichiers, et que tsc génère des fichiers .js, l'utilisation d'extensions .js dans votre source garantit que les imports fonctionnent dans les deux scénarios.

Pas par défaut. Les enums nécessitent une transformation de code, pas seulement la suppression de types. Vous pouvez activer le flag --experimental-transform-types pour supporter les enums, namespaces et parameter properties, mais cela ajoute de la complexité. Pour des configurations plus simples, envisagez d'utiliser des objets const avec des assertions as const comme alternative aux enums.

Pour la plupart des cas d'usage, non. La suppression native de types de Node 24 gère l'exécution directe de .ts. Des outils comme ts-node et tsx sont des commodités optionnelles qui ajoutent le support de tsconfig.json, la résolution d'alias de chemins et les transformations TypeScript complètes sans flags. Utilisez-les uniquement si votre configuration nécessite ces fonctionnalités.

Lors de l'utilisation de la suppression native de types, Node exécute directement vos fichiers .ts, donc les numéros de ligne dans les traces de pile correspondent à votre source. Pour le code compilé, activez sourceMap dans tsconfig.json et Node utilisera automatiquement les fichiers .js.map pour afficher les emplacements TypeScript originaux dans les erreurs et les sessions de débogage.

Complete picture for complete understanding

Capture every clue your frontend is leaving so you can instantly get to the root cause of any issue with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data.

Check our GitHub repo and join the thousands of developers in our community.

OpenReplay