TypeScript - null vs. undefined

Bonjour, futurs programmeurs ! Aujourd'hui, nous allons plonger dans un sujet passionnant qui souvent embrouille les débutants : la différence entre null et undefined en TypeScript. Ne vous inquiétez pas si vous vous sentez un peu submergé - je me souviens que lorsque j'ai rencontré pour la première fois ces concepts, j'étais également très confus ! Mais d'ici la fin de cette leçon, vous serez un pro pour distinguer ces deux valeurs spéciales. Commençons !

TypeScript - null vs. undefined

Qu'est-ce que null ?

En TypeScript (et JavaScript), null est une valeur spéciale qui représente l'absence intentionnelle de toute valeur d'objet. C'est comme dire : "Il devrait y avoir quelque chose ici, mais pour le moment, il n'y a rien."

Voyons quelques exemples pour mieux comprendre :

let monAnimal: string | null = null;
console.log(monAnimal); // Output : null

// Plus tard dans le code...
monAnimal = "Fluffy";
console.log(monAnimal); // Output : Fluffy

Dans cet exemple, nous déclarons une variable monAnimal qui peut être soit une chaîne de caractères, soit null. Initialement, nous la définissons à null, indiquant que nous n'avons pas d'animal encore. Plus tard, lorsque nous en avons un, nous affectons le nom "Fluffy" à monAnimal.

Voici un autre exemple :

function findUser(id: number): { name: string } | null {
// Imaginez que nous cherchons dans une base de données
if (id === 1) {
return { name: "Alice" };
} else {
return null;
}
}

let utilisateur = findUser(1);
console.log(utilisateur); // Output : { name: "Alice" }

utilisateur = findUser(2);
console.log(utilisateur); // Output : null

Dans ce cas, notre fonction findUser renvoie soit un objet utilisateur, soit null si aucun utilisateur n'est trouvé. C'est un pattern commun en programmation - utiliser null pour indiquer qu'une recherche ou une opération n'a pas donné de résultat.

Qu'est-ce que undefined ?

Maintenant, parlons de undefined. Cette valeur spéciale représente une variable qui a été déclarée mais qui n'a pas encore été affectée d'une valeur. C'est comme une boîte vide - elle existe, mais il n'y a rien dedans encore.

Voici quelques exemples pour illustrer undefined :

let monNom: string;
console.log(monNom); // Output : undefined

// Plus tard dans le code...
monNom = "John";
console.log(monNom); // Output : John

function saluer(nom?: string) {
console.log(nom);
}

saluer(); // Output : undefined
saluer("Alice"); // Output : Alice

Dans la première partie, nous déclarons monNom mais ne lui affectons pas de valeur. TypeScript lui donne automatiquement la valeur undefined. Plus tard, nous affectons une valeur, et il n'est plus undefined.

Dans la fonction saluer, nous utilisons un paramètre optionnel. Si nous appelons la fonction sans fournir d'argument, le paramètre nom sera undefined.

Voici un autre scénario où vous pourriez rencontrer undefined :

let personne = {
name: "Bob",
age: 30
};

console.log(personne.name); // Output : Bob
console.log(personne.job); // Output : undefined

Dans ce cas, personne.job est undefined parce que nous n'avons jamais défini une propriété job pour notre objet personne.

Null vs. Undefined : Clés Differences

Maintenant que nous avons exploré null et undefined separately, comparons-les côte à côte pour mieux comprendre leurs différences.

Aspect null undefined
Signification Absence intentionnelle de toute valeur d'objet Variable déclarée mais non affectée d'une valeur
Type Objet Undefined
Dans JSON Valide Invalid
Paramètre par défaut de fonction Non utilisé comme valeur par défaut Utilisé comme valeur par défaut pour les paramètres optionnels
Égalité null == undefined (vrai), null === undefined (faux) undefined == null (vrai), undefined === null (faux)

Voyons quelques exemples de code pour illustrer ces différences :

// Vérification des types
console.log(typeof null);       // Output : "object"
console.log(typeof undefined);  // Output : "undefined"

// Sérialisation JSON
console.log(JSON.stringify({ a: null }));     // Output : {"a":null}
console.log(JSON.stringify({ a: undefined })); // Output : {}

// Paramètres par défaut de fonction
function direBonjour(nom: string = "World") {
console.log(`Bonjour, ${nom} !`);
}

direBonjour();        // Output : Bonjour, World!
direBonjour(undefined); // Output : Bonjour, World!
direBonjour(null);    // Output : Bonjour, null!

// Égalité
console.log(null == undefined);  // Output : true
console.log(null === undefined); // Output : false

Dans la pratique, le choix entre null et undefined dépend souvent de la préférence personnelle ou d'équipe. Cependant, comprendre les différences peut vous aider à écrire un code plus précis et exempt de bugs.

Voici un exemple final pour tout relier :

function processUser(user: { name: string, age?: number } | null | undefined) {
if (user === null) {
console.log("Utilisateur explicitement mis à null");
} else if (user === undefined) {
console.log("Utilisateur non fourni");
} else {
console.log(`Traitement de l'utilisateur : ${user.name}, Âge : ${user.age ?? "Inconnu"}`);
}
}

processUser(null);                    // Output : Utilisateur explicitement mis à null
processUser(undefined);               // Output : Utilisateur non fourni
processUser({ name: "Alice" });       // Output : Traitement de l'utilisateur : Alice, Âge : Inconnu
processUser({ name: "Bob", age: 30 }); // Output : Traitement de l'utilisateur : Bob, Âge : 30

Cette fonction montre comment nous pourrions gérer null, undefined, et les objets utilisateur valides différemment dans un scénario du monde réel.

Et voilà ! Vous avez maintenant appris les ficelles de null et undefined en TypeScript. Souvenez-vous, la pratique rend parfait, donc n'ayez pas peur d'expérimenter avec ces concepts dans votre propre code. Bon codage, et puissent vos variables être intentionnellement null ou undefined !

Credits: Image by storyset