Skip to main content

3. Typescript

Les limites de JS

JavaScript et Node.js sont des technologies puissantes, mais leur typage dynamique peut poser de sérieux problèmes, notamment dans les projets de grande envergure.

Le problème du typage dynamique

En JavaScript, les types sont déterminés à l'exécution (runtime) et non à la compilation. Cela signifie qu'une variable peut changer de type à tout moment, et les erreurs de type ne sont détectées que lorsque le code est exécuté.

Imaginez une fonction simple d'addition :

import { add } from './math.js'

// Cas normal
console.log(add(2, 3))

console.log(add(2, 'three'))
console.log(add('10', 3))

// Conversions implicites
console.log(add(10, '3'))
console.log(add('10', '3'))

// Données manquantes
console.log(add(10, undefined))
console.log(add(null, 3))

Conséquences :

  • Le code compile sans erreurs
  • Le bug n'apparaît qu'en production, quand un utilisateur envoie des données incorrectes
  • Les résultats sont incorrects sans lever d'exception
  • Difficile à déboguer, car l'erreur est silencieuse

TypeScript

TypeScript est une extension de JavaScript. Créé par Microsoft, il est conçu pour rendre le code JavaScript plus fiable, lisible et maintenable, notamment dans les projets d'envergure.

L'un des plus grands avantages de TypeScript est la détection des erreurs lors de la compilation, contrairement à JavaScript où les erreurs ne sont souvent détectées qu'à l'exécution. Voici un exemple simple :

Installation

Pour installer Typescript, comme tous packages, deux solutions s'offrent à vous. Soit vous l'installez globalement sur votre machine, soit vous l'ajoutez en tant que dépendance de votre projet.

# Installation globale
npm install -g typescript

# Installation locale
npm install -d typescript

Configuration

Pour configurer TypeScript, vous pouvez créer une configuration par défaut en utilisant la commande suivante :

# Installation globale
tsc --init

# Installation locale
npx tsc --init

Cette commande va générer un fichier tsconfig.json qui contient la configuration de TypeScript pour votre projet. Vous pouvez personnaliser ce fichier en fonction de vos besoins. Nous n'allons pas rentrer dans le détail de la configuration de Typescript ici, mais vous pouvez consulter la documentation officielle.

Compilation d'un fichier TypeScript

Nous allons modifier notre fichier index.js en index.ts pour le transformer en fichier TypeScript. TypeScript utilise l'extension .ts pour les fichiers.

Pour pouvoir lancer notre application NodeJS, nous devons compiler notre fichier TypeScript en JavaScript. Pour cela, nous utilisons la commande tsc (TypeScript Compiler).

# Compilation du fichier TypeScript
tsc

Elle peut aussi être écrit dans un script dans le fichier package.json pour simplifier la commande.

{
"scripts": {
"build": "tsc"
}
}

Cette commande va générer un fichier index.js dans le même dossier que le fichier index.ts. Vous pouvez ensuite exécuter ce fichier avec Node.js comme d'habitude. Si vous souhaitez générer les fichiers compilés dans un dossier spécifique, vous pouvez modifier le fichier tsconfig.json en ajoutant la clé outDir.

{
"compilerOptions": {
"outDir": "./dist"
}
}

Reprise de l'exemple précedent

function add(a: number, b: number): number {
return a + b
}

//Erreur de compilation : Argument of type 'string' is not assignable to parameter of type 'number'
add(2, 'three')

// Erreur de compilation : Argument of type 'string' is not assignable to parameter of type 'number'
add('10', 3)

// Erreur de compilation : Argument of type 'undefined' is not assignable to parameter of type 'number'
add(10, undefined)

// Erreur de compilation : Argument of type 'null' is not assignable to parameter of type 'number'
add(null, 3)

// Cas valide
add(2, 3) // 5

Avantages :

  • Erreurs détectées pendant le développement
  • Autocomplétion intelligente dans l'éditeur
  • Refactoring sécurisé
  • Documentation intégrée via les types
  • Moins de bugs en production

Gestion du hot-reload

Pour éviter de devoir compiler à chaque modification de fichier, vous pouvez utiliser un outil comme tsx qui permet d'exécuter directement des fichiers TypeScript sans les compiler.

# Installation de tsx
npm install -d tsx

Vous pouvez ensuite exécuter votre fichier TypeScript directement avec tsx.

tsx index.ts

tsx dispose d'un mode watch intégré qui relance automatiquement votre code à chaque modification de fichier. Vous n'avez donc plus besoin de nodemon pour le hot-reload.

{
"scripts": {
"dev": "tsx watch ./src/index.ts"
}
}

Types de bases

TypeScript ne permet pas simplement de déclarer des types ou de compiler du code. Il ajoute également des fonctionnalités qui rendent le code plus lisible et maintenable.

Certaines de ces notions doivent vous être familières si vous avez déjà travaillé avec des langages de programmation comme Java ou C#.

Variables

TypeScript permet de définir explicitement les types de variables.

let name: string = 'Alice'
let age: number = 25
let isStudent: boolean = true

Fonctions

Ajoutez des types pour les arguments et la valeur de retour.

function greet(name: string): string {
return `Hello, ${name}`
}

Interfaces

Les interfaces permettent de définir des structures pour vos objets.

interface User {
name: string
age: number
isAdmin?: boolean // Propriété optionnelle
}

const user: User = { name: 'Bob', age: 30 }

Type Aliases

Créez des alias pour des types complexes.

type Point = { x: number; y: number }

const point: Point = { x: 10, y: 20 }

Types avancés

Union Types

Un argument peut accepter plusieurs types.

function printId(id: number | string): void {
console.log(`ID: ${id}`)
}

Enums

Les énumérations permettent de définir un ensemble de constantes nommées.

enum Direction {
Up = 'UP',
Down = 'DOWN',
Left = 'LEFT',
Right = 'RIGHT',
}

Les packages @types

Certains packages JavaScript n'ont pas de types TypeScript par défaut. Pour les utiliser dans un projet TypeScript, vous pouvez installer des packages @types. Ce sont des packages que la communauté TypeScript a créés pour ajouter des types à des packages JavaScript existants.

npm install -d @types/nom_du_paquet

Par exemple pour récupérer les types de node :

npm install -d @types/node

Dans les prochains chapitres, nous prendrons l'habitude d'installer aussi les types des packages que nous utilisons.