Comment exécuter TypeScript nativement dans Node.js

Node.js 23.6.0 marque un tournant pour les développeurs TypeScript : vous pouvez désormais exécuter directement les fichiers .ts
sans outils de transpilation comme ts-node ou tsc. Cette prise en charge native de TypeScript simplifie les flux de développement en éliminant les étapes de compilation tout en maintenant la sécurité des types via votre IDE.
Ce guide couvre tout ce dont vous avez besoin pour exécuter TypeScript nativement dans Node.js, de la configuration de base aux considérations de production. Vous apprendrez comment fonctionne la suppression de types, quelles fonctionnalités TypeScript sont prises en charge, et comment configurer vos projets pour une compatibilité optimale.
Points clés à retenir
- Node.js 23.6.0 exécute les fichiers TypeScript directement sans transpilation
- La suppression de types retire les annotations tout en préservant la structure du code
- La plupart des fonctionnalités TypeScript courantes fonctionnent, mais les enums et namespaces nécessitent des contournements
- Les instructions d’import doivent inclure l’extension
.ts
- L’exécution native offre des temps de démarrage 2 à 3 fois plus rapides comparé aux outils traditionnels
Démarrage rapide : Exécuter TypeScript dans Node.js 23.6.0
Commençons avec un fichier TypeScript simple pour démontrer l’exécution native :
// greeting.ts
function greet(name: string): string {
return `Hello, ${name}!`
}
console.log(greet("TypeScript"))
Avec Node.js 23.6.0 ou ultérieur, exécutez ceci directement :
node greeting.ts
C’est tout—aucune étape de compilation requise. Node.js supprime les annotations de types et exécute le JavaScript restant.
Pour vérifier votre version de Node.js :
node --version # Devrait être v23.6.0 ou supérieur
Vous verrez un avertissement expérimental au premier lancement :
ExperimentalWarning: Type Stripping is an experimental feature and might change at any time
Pour supprimer cet avertissement en développement :
node --disable-warning=ExperimentalWarning greeting.ts
Ou le définir de façon permanente :
export NODE_OPTIONS="--disable-warning=ExperimentalWarning"
Comprendre la suppression de types dans Node.js
La suppression de types diffère fondamentalement de la transpilation TypeScript traditionnelle. Au lieu de transformer TypeScript en JavaScript, Node.js supprime simplement les annotations de types tout en préservant la structure originale du code.
Voici ce qui se passe lors de la suppression de types :
// TypeScript original
function calculate(a: number, b: number): number {
return a + b
}
// Après suppression de types (ce que Node.js exécute)
function calculate(a , b ) {
return a + b
}
Notez la préservation des espaces—cela maintient des numéros de ligne précis pour le débogage sans nécessiter de source maps.
Avantages en termes de performances
L’exécution native de TypeScript offre des améliorations significatives de performances :
- Pas de surcharge de transpilation : Exécution directe sans étapes intermédiaires
- Temps de démarrage plus rapides : ~45ms vs. 120ms avec ts-node
- Utilisation mémoire réduite : Pas de transpilateur chargé en mémoire
- Débogage simplifié : Numéros de ligne originaux préservés
Évolution de la prise en charge TypeScript dans Node.js
Comprendre la progression vous aide à choisir la bonne approche :
v22.6.0 : Suppression de types initiale
node --experimental-strip-types app.ts
Suppression de types basique uniquement—pas de prise en charge de la syntaxe spécifique à TypeScript.
v22.7.0 : Transformation de types
node --experimental-transform-types app.ts
Ajout de la prise en charge des enums et namespaces via transformation.
v23.6.0 : Suppression de types par défaut
node app.ts # Suppression de types activée par défaut
Aucun flag nécessaire pour l’exécution TypeScript de base.
Fonctionnalités TypeScript prises en charge et limitations
Ce qui fonctionne
TypeScript natif dans Node.js prend en charge la plupart des fonctionnalités TypeScript courantes :
// ✅ Annotations de types
let count: number = 0
// ✅ Interfaces
interface User {
id: number
name: string
}
// ✅ Alias de types
type Status = 'active' | 'inactive'
// ✅ Génériques
function identity<T>(value: T): T {
return value
}
// ✅ Imports de types
import type { Config } from './types.ts'
Ce qui ne fonctionne pas
Certaines fonctionnalités spécifiques à TypeScript nécessitent des contournements :
Fonctionnalité | Prise en charge | Contournement |
---|---|---|
Enums | ❌ | Utiliser des types union ou des objets const |
Namespaces | ❌ | Utiliser les modules ES |
Propriétés de paramètres | ❌ | Déclarations de propriétés explicites |
JSX/TSX | ❌ | Utiliser la transpilation traditionnelle |
Décorateurs | ❌ | Attendre la prise en charge V8 |
Exemples de contournements :
// ❌ Enum (non pris en charge)
enum Status {
Active,
Inactive
}
// ✅ Alternative avec type union
type Status = 'active' | 'inactive'
// ✅ Alternative avec objet const
const Status = {
Active: 'active',
Inactive: 'inactive'
} as const
Discover how at OpenReplay.com.
Extensions de fichiers et systèmes de modules
Node.js utilise les extensions de fichiers pour déterminer la gestion des modules :
.ts
- Suit le champ"type"
de package.json (ESM ou CommonJS).mts
- Toujours traité comme ESM.cts
- Toujours traité comme CommonJS
Important : Les imports locaux doivent inclure l’extension .ts
:
// ❌ TypeScript traditionnel
import { utils } from './utils'
// ✅ TypeScript natif Node.js
import { utils } from './utils.ts'
Configurer tsconfig.json pour TypeScript natif
Bien que Node.js ne lise pas tsconfig.json lors de l’exécution, une configuration appropriée assure la prise en charge IDE et la vérification de types :
{
"compilerOptions": {
"target": "esnext",
"module": "nodenext",
"moduleResolution": "nodenext",
"allowImportingTsExtensions": true,
"rewriteRelativeImportExtensions": false,
"verbatimModuleSyntax": true,
"strict": true,
"noEmit": true
}
}
Paramètres clés expliqués :
allowImportingTsExtensions
: Permet.ts
dans les chemins d’importrewriteRelativeImportExtensions
: Défini à false pour préserver les extensions.ts
verbatimModuleSyntax
: Force les imports de types explicitesnoEmit
: Empêche la génération accidentelle de JavaScript
Exécutez la vérification de types séparément :
tsc --noEmit
Guide de migration depuis les outils TypeScript traditionnels
Migration depuis ts-node
- Supprimez la dépendance ts-node :
npm uninstall ts-node
- Mettez à jour les scripts package.json :
// Avant
"scripts": {
"dev": "ts-node src/index.ts"
}
// Après
"scripts": {
"dev": "node src/index.ts"
}
- Gérez les fonctionnalités non prises en charge (convertissez les enums en unions)
Migration depuis la compilation tsc
- Supprimez les étapes de build :
// Supprimez ces scripts
"scripts": {
"build": "tsc",
"start": "node dist/index.js"
}
// Utilisez ceci à la place
"scripts": {
"start": "node src/index.ts"
}
- Mettez à jour les pipelines CI/CD pour ignorer la compilation
Comparaison des performances
L’exécution native de TypeScript montre des améliorations significatives :
Métrique | TypeScript natif | ts-node | tsc + node |
---|---|---|---|
Temps de démarrage | ~45ms | ~120ms | ~200ms |
Utilisation mémoire | Référence | +30MB | +10MB |
Étape de build | Aucune | Aucune | Requise |
Pièges courants et solutions
Erreurs de chemins d’import
// Erreur : Cannot find module './utils'
import { helper } from './utils'
// Solution : Inclure l'extension .ts
import { helper } from './utils.ts'
Syntaxe non prise en charge
// Erreur : Enums are not supported
enum Color { Red, Blue }
// Solution : Utiliser un objet const
const Color = { Red: 0, Blue: 1 } as const
Confusion sur la vérification de types
Rappel : Node.js n’effectue pas de vérification de types. Exécutez toujours tsc --noEmit
pour la validation des types.
Considérations de production
Quand utiliser TypeScript natif
- Environnements de développement
- Prototypes et expérimentations
- Petits scripts et utilitaires
- Équipes prêtes pour les fonctionnalités expérimentales
Quand éviter
- Applications de production (jusqu’à stabilisation)
- Projets nécessitant toutes les fonctionnalités TypeScript
- Équipes ayant besoin d’outils stables
- Pipelines de build complexes
Ajustements Docker
# Avant
FROM node:23-alpine
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
CMD ["node", "dist/index.js"]
# Après
FROM node:23-alpine
COPY package*.json ./
RUN npm ci
COPY . .
CMD ["node", "src/index.ts"]
Conclusion
La prise en charge native de TypeScript dans Node.js 23.6.0 représente une simplification significative pour les flux de développement. En éliminant les étapes de transpilation, vous pouvez vous concentrer sur l’écriture de code plutôt que sur la configuration d’outils de build. Bien que des limitations existent—particulièrement autour de la syntaxe spécifique à TypeScript—les avantages pour la plupart des scénarios de développement sont convaincants.
Commencez par essayer TypeScript natif dans votre environnement de développement, migrez progressivement les projets existants, et préparez-vous pour un futur où TypeScript s’exécute partout où JavaScript fonctionne. À mesure que cette fonctionnalité se stabilise, attendez-vous à une adoption plus large et des capacités étendues dans les prochaines versions de Node.js.
FAQ
Bien que techniquement possible, ce n'est pas encore recommandé pour un usage en production. La fonctionnalité est encore expérimentale et peut changer. Utilisez-la pour les environnements de développement, les prototypes et les applications non critiques. Pour la production, continuez à utiliser la transpilation traditionnelle jusqu'à ce que la fonctionnalité devienne stable.
Oui, vous devriez conserver TypeScript comme dépendance de développement pour la vérification de types. Node.js ne fait que supprimer les types sans les valider. Exécutez tsc --noEmit séparément pour détecter les erreurs de types pendant le développement ou dans votre pipeline CI.
TypeScript natif nécessite des extensions .ts explicites dans les chemins d'import, contrairement aux outils TypeScript traditionnels. Mettez à jour tous les imports locaux de './module' vers './module.ts'. Les imports de packages externes n'ont pas besoin d'extensions.
Remplacez les enums par des types union pour les cas simples ou des objets const avec assertion as const pour les enums numériques. Pour les enums de chaînes, les types union fonctionnent parfaitement. Cette approche est en fait plus tree-shakeable et s'aligne mieux avec les pratiques TypeScript modernes.
L'équipe Node.js se concentre sur la suppression de types plutôt que sur la transpilation complète pour des raisons de performances. Les fonctionnalités nécessitant une transformation runtime comme les enums et décorateurs pourraient obtenir une prise en charge quand V8 les implémentera nativement, mais l'objectif est un traitement rapide et minimal plutôt qu'une compatibilité TypeScript complète.
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.