TypeScript avec Node.js
Initialiser un projet Node.js + TypeScript
Un projet TypeScript pour Node.js se monte en quelques étapes. On initialise d'abord le projet Node.js, puis TypeScript, et on organise les dossiers.
# 1. Initialiser le projet Node.js
npm init -y
# 2. Installer TypeScript
npm install --save-dev typescript
# 3. Générer le fichier tsconfig.json
npx tsc --init
Structure de dossiers recommandée :
mon-projet/
├── src/ # sources TypeScript
│ └── index.ts
├── dist/ # JavaScript compilé (généré)
├── node_modules/
├── package.json
└── tsconfig.json
Installer @types/node
Node.js a ses propres API : fs, path, http, process…
TypeScript ne connaît pas ces types par défaut.
Le paquet @types/node les fournit.
# Types Node.js pour TypeScript
npm install --save-dev @types/node
Une fois installé, tu bénéficies de l'autocomplétion et du typage strict pour toutes les API natives Node.js.
Indispensable dès que tu importes fs ou path.
ts-node et ts-node-dev — exécuter TypeScript directement
Normalement, il faut compiler le TypeScript en JavaScript avant de l'exécuter.
ts-node court-circuite cette étape : il exécute .ts directement dans Node.js.
Pratique en développement.
# Installer ts-node et ts-node-dev
npm install --save-dev ts-node ts-node-dev
# Exécuter un fichier TypeScript
npx ts-node src/index.ts
# Avec rechargement automatique (comme nodemon)
npx ts-node-dev src/index.ts
ts-node-dev surveille les fichiers et redémarre automatiquement à chaque modification,
exactement comme nodemon mais avec TypeScript natif.
Utilise-le systématiquement pendant le développement — tu évites de taper tsc && node dist/… à chaque changement.
tsconfig.json pour Node.js
Le fichier tsconfig.json généré par tsc --init contient beaucoup d'options commentées.
Voici une configuration minimaliste et efficace pour Node.js :
{
"compilerOptions": {
"target": "ES2022", // Version JS cible
"module": "commonjs", // Format de modules Node.js
"rootDir": "./src", // Sources TypeScript
"outDir": "./dist", // Destination du JS compilé
"strict": true, // Toutes les vérifications strictes
"esModuleInterop": true, // Compatibilité imports CommonJS
"skipLibCheck": true, // Ignore les erreurs dans node_modules
"resolveJsonModule": true // Permet d'importer des .json
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}
Les deux clés les plus importantes : "rootDir" indique où se trouvent tes sources,
"outDir" où TypeScript écrit le JavaScript compilé.
TypeScript reproduit la structure de src/ dans dist/.
Scripts npm : build, dev, start
Centralise toutes les commandes dans package.json.
Un projet TypeScript Node.js a typiquement trois scripts essentiels :
{
"scripts": {
"build": "tsc",
"dev": "ts-node-dev --respawn src/index.ts",
"start": "node dist/index.js"
}
}
npm run build— compile tout le TypeScript versdist/npm run dev— démarre avec rechargement automatique, sans compilation préalablenpm start— exécute le JavaScript compilé en production
Typer les modules Node.js : fs, path, http
Avec @types/node installé, tous les modules natifs Node.js sont typés.
Les fonctions retournent les bons types, les erreurs sont catchées avec le bon type.
import fs from "fs";
import path from "path";
import http from "http";
// fs : lecture d'un fichier texte
const contenu: string = fs.readFileSync("data.txt", "utf-8");
// path : construction de chemins portables
const chemin: string = path.join(__dirname, "data", "config.json");
// http : serveur HTTP minimal
const server = http.createServer(
(req: http.IncomingMessage, res: http.ServerResponse) => {
res.writeHead(200, { "Content-Type": "text/plain" });
res.end("Bonjour depuis TypeScript !");
}
);
server.listen(3000, () => {
console.log("Serveur sur http://localhost:3000");
});
Gestion des erreurs typée
En TypeScript, le type natif Error est disponible partout.
Pour aller plus loin, tu peux créer des classes d'erreur personnalisées qui étendent Error —
utile pour distinguer les erreurs métier des erreurs système.
// Erreur personnalisée pour les fichiers introuvables
class FichierIntrouvableError extends Error {
constructor(public chemin: string) {
super(`Fichier introuvable : ${chemin}`);
this.name = "FichierIntrouvableError";
}
}
// Utilisation avec instanceof pour filtrer le type d'erreur
function lireFichier(chemin: string): string {
try {
return fs.readFileSync(chemin, "utf-8");
} catch (e) {
throw new FichierIntrouvableError(chemin);
}
}
try {
const contenu = lireFichier("manquant.txt");
} catch (e) {
if (e instanceof FichierIntrouvableError) {
console.error("Chemin :", e.chemin);
}
}
Avec strict: true, le paramètre e d'un bloc catch est de type unknown —
pas any. Tu dois vérifier son type avec instanceof avant d'accéder à ses propriétés.
C'est volontaire : TypeScript t'oblige à ne pas supposer ce qui a été lancé.
Checklist de bonnes pratiques
Un projet TypeScript Node.js bien configuré respecte ces points dès le départ. Mieux vaut les mettre en place au début que corriger 200 erreurs plus tard.
-
strict: truedans tsconfig.json. Active toutes les vérifications :noImplicitAny,strictNullChecks,noImplicitThis… Ne pas le désactiver parce que "ça fait des erreurs" — les erreurs sont le point. -
Pas de
anyimplicite. Si tu dois contourner le typage, utiliseunknownpuis affine avec des gardes de type. Leanyexplicite avec un commentaire est acceptable ponctuellement — leanysilencieux, jamais. - Linter : ESLint + typescript-eslint. TypeScript détecte les erreurs de types. ESLint détecte les mauvaises pratiques. Les deux sont complémentaires.
-
Ajoute
dist/etnode_modules/dans.gitignore. Le dossierdist/est généré — il ne va pas dans le dépôt Git. -
En production, compile d'abord, exécute ensuite.
ts-nodeest réservé au développement. En prod :npm run build && npm start.
npm install --save-dev eslint @eslint/js typescript-eslint
# eslint.config.js (format plat, ESLint v9+)
import eslint from "@eslint/js";
import tseslint from "typescript-eslint";
export default tseslint.config(
eslint.configs.recommended,
...tseslint.configs.recommended
);
- Pour Node.js :
npm install --save-dev typescript @types/node, puisnpx tsc --init. ts-node-devexécute et recharge le TypeScript directement en développement.- Dans
tsconfig.json: configurerootDir,outDir,targetetmodule: "commonjs". - Les types des modules Node.js viennent de
@types/node— sans eux, pas d'autocomplétion. - Active
strict: truedès le départ. Ajoute ESLint + typescript-eslint pour aller plus loin. - Bilan du module : tu sais typer des variables, fonctions, objets, interfaces et génériques. Tu maîtrises les types avancés, la POO orientée TypeScript, les modules, et maintenant l'intégration Node.js. TypeScript n'est plus une contrainte — c'est un filet de sécurité qui te fait écrire un meilleur code.