Mutable et Immutable en TypeScript

Mutable et Immutable en TypeScript

Cet article explique les concepts de mutable et immutable en TypeScript.

YouTube Video

Mutable et Immutable en TypeScript

Qu'est-ce que le Mutable ?

Mutable signifie qu'une valeur peut être modifiée. Les types par référence comme les objets et les tableaux sont des exemples typiques de structures de données mutables.

Exemple d'un objet mutable

1type Person = { name: string; age: number };
2
3// Mutable Example: Object
4let person: Person = { name: "Alice", age: 25 };
5person.age = 26;
6console.log(person); // { name: "Alice", age: 26 }

Dans ce code, la propriété age de l'objet person est modifiée de 25 à 26. Étant donné que les objets sont passés par référence, le contenu à l'adresse mémoire stockée dans la variable person est modifié.

Exemple d'un tableau mutable

1// Mutable Example: Array
2let numbers: number[] = [1, 2, 3];
3numbers.push(4);
4console.log(numbers); // [1, 2, 3, 4]

Dans ce code, la méthode push est utilisée pour ajouter un nouvel élément 4 au tableau d'origine. Cela modifie le tableau d'origine, ce qui en fait une opération mutable.

Exemple dans une fonction

1// Mutable Example: Function
2function append(arr: number[], value: number): void {
3    arr.push(value); // Modify the original array
4    console.log(arr);
5}
6
7let nums: number[] = [1, 2, 3];
8append(nums, 4);
9console.log(nums); // [1, 2, 3, 4]

Lorsqu'on effectue des opérations mutables à l'intérieur d'une fonction, le tableau d'origine est également modifié.

Qu'est-ce que l'Immutable ?

Immutable signifie qu'une valeur ne peut pas être modifiée. Les types primitifs sont fondamentalement immutables.

Exemple d'un type primitif immutable

1// Immutable Example: String
2let str: string = "hello";
3str[0] = "H"; // Error: Index assignment is not allowed
4console.log(str); // "hello"

Tenter de changer le premier caractère de la chaîne str en H échoue parce que les chaînes sont immutables.

Exemple dans une fonction

1// Immutable Example: Function
2function increment(num: number): number {
3    num++; // This modifies only the local copy of num
4    return num;
5}
6
7let number: number = 10;
8console.log(increment(number)); // 11
9console.log(number); // 10 (original number remains unchanged)

Comme les nombres sont immutables, les opérations dans une fonction n'affectent pas la variable d'origine.

Opérations immutables sur les tableaux

Les tableaux sont mutables, mais en créant un nouveau tableau au lieu de modifier l'original, des opérations immutables peuvent être réalisées.

1// Create an array of numbers
2let numbers: number[] = [1, 2, 3];
3
4// Immutable Example: Creating a new array
5let newNumbers: number[] = [...numbers, 4];
6
7console.log(numbers); // [1, 2, 3] (original array is unchanged)
8console.log(newNumbers); // [1, 2, 3, 4] (new array with an added element)

Ici, la syntaxe de décomposition (...) est utilisée pour créer un nouveau tableau newNumbers. Comme le tableau numbers original reste inchangé, il s'agit d'une opération immuable.

Avantages d'utiliser des structures de données immuables

Amélioration de la prévisibilité

Les données immuables ne changent pas, ce qui rend les modifications inattendues moins probables et réduit les risques de bogues.

Compatibilité avec des bibliothèques basées sur l'immuabilité

Les bibliothèques telles que React et Redux sont souvent conçues sur la base de données immuables, ce qui facilite la gestion de l'état lorsqu'elles sont utilisées correctement.

Rendre les objets immuables avec Object.freeze

Object.freeze peut être utilisé pour empêcher les modifications d'un objet.

1// Create a frozen object (properties cannot be modified)
2const person = Object.freeze({ name: "Alice", age: 25 });
3
4// Attempt to modify a property (ignored in non-strict mode, error in strict mode)
5person.age = 26;
6
7console.log(person); // { name: "Alice", age: 25 }

Cependant, Object.freeze effectue uniquement un gel superficiel, ce qui signifie que les propriétés des objets imbriqués restent modifiables.

1// Create a frozen object with a nested object
2const user: Readonly<{ profile: { name: string } }> = Object.freeze({
3    profile: { name: "Bob" }
4});
5
6// Attempt to modify a nested property (this works because Object.freeze() is shallow)
7user.profile.name = "Charlie"; // No TypeScript error, but still mutable
8
9console.log(user.profile.name); // "Charlie" (nested object is still mutable)

Pour créer un objet complètement immuable, un gel profond est nécessaire.

 1// Function to deeply freeze an object, making all nested objects immutable
 2function deepFreeze<T>(obj: T): Readonly<T> {
 3    Object.freeze(obj);
 4    Object.getOwnPropertyNames(obj).forEach(prop => {
 5        const value = (obj as any)[prop];
 6        if (typeof value === "object" && value !== null) {
 7            deepFreeze(value);
 8        }
 9    });
10    return obj;
11}
12
13// Create a deeply frozen object
14const user = deepFreeze({
15  profile: { name: "Bob" }
16});
17
18// Attempt to modify a nested property
19// (this will now throw an error in strict mode)
20user.profile.name = "Charlie";  // No TypeScript error, but modification is not allowed at runtime
21
22console.log(user.profile.name); // "Bob" (unchanged due to deep freeze)

Résumé

  • Les données mutables sont modifiables, et incluent les objets et les tableaux.
  • Les données immuables sont non modifiables, et incluent les types primitifs tels que les chaînes de caractères et les nombres.
  • En utilisant la syntaxe de décomposition ou des méthodes comme map, des opérations sur des données immuables peuvent être effectuées.
  • Object.freeze et deepFreeze peuvent être utilisés pour empêcher les modifications des objets.
  • L'utilisation de données immuables aide à écrire un code plus prévisible et moins sujet aux erreurs.

Adopter une conception immuable améliore la sécurité et la lisibilité du code, alors profitez-en pleinement !

Vous pouvez suivre l'article ci-dessus avec Visual Studio Code sur notre chaîne YouTube. Veuillez également consulter la chaîne YouTube.

YouTube Video