devstory

Espaces (Namespaces) de noms dans TypeScript

Suivez-nous sur notre fanpage pour recevoir des notifications chaque fois qu'il y a de nouveaux articles. Facebook

1- Qu'est-ce que c'est l'espace de nom (Namespace) ?

Dans JavaScript ES6, le mot-clef module est utilisé pour définir un module, cela vous permet de définir plusieurs modules dans un fichier. TypeScript utilise le mot-clef namespace avec une syntaxe et des objectifs similaires.
Consulter l'article suivant pour comprendre le concept de module et les mots-clefs export/import dans TypeScript :
Remarque : Les mots clefs "module" et "namespace" peuvent être utilisés dans TypeScript avec une syntaxe et une utilisation similaires. Cependant, la documentation TypeScript déconseille l'utilisation du mot-clef "module" dans le code TypeScript, il ne doit être utilisé que dans le code JavaScript.
Dans TypeScript, le mot-clef "namespace" est légèrement plus puissant que le mot-clef "module". Vous pouvez définir un module sur plusieurs fichiers avec le mot-clef "namespace" et utiliser le drapeau "--outFile" si vous voulez qu'ils soient regroupés dans un seul fichier au moment de la compilation.
Dans cet article nous utiliserons le terme "espace de noms" (namespace), vous pouvez également comprendre qu'il s'apparente à la notion de module en JavaScript. Fondamentalement, "l'espace de noms" (ainsi que le module) est un moyen de regrouper des variables, des fonctions, des classes, ... avec la même relation dans un groupe logique. Cela nous aide à gérer et à maintenir facilement l'application.

2- La syntaxe

Par défaut, toutes les ressources de code définies dans un espace de noms ont une portée locale (local scope). Cela signifie que l'environnement externe ne les connaît pas à moins qu'ils ne soient définis avec le mot-clef export :
file1.ts

namespace Namespace_Name {
   export let sampleVariable: number = 100;
   export class SampleClass {
      // ...
   }
   export interface SampleInterface {
      // ...
   }
   export function sampleFunction() {
      // ...
   }
   // ...
}
Dans un autre fichier, on peut accéder aux ressources de code exportées dans un espace de noms avec la syntaxe suivante :
file2.ts

/// <reference path = "./file1.ts" />

Namespace_Name.sampleVariable;
Namespace_Name.sampleFunction();
Namespace_Name.SampleClass;
/// <reference path = "..." />
/// <reference path="..."/> est une directive nécessaire pour indiquer au compilateur où se trouve le fichier de définition d'espace de noms.

3- Par exemple

Dans cet exemple, on définit un espace de noms "MathLib" sur trois fichiers distincts, Math_file1.ts, Math_file2.ts et Math_file3.ts. Utiliser ensuite l'espace de noms "MathLib" dans le fichier test.ts. Enfin, exécuter l'application dans l'environnement NodeJS et Web.
Le fichier Math_file1.ts définit l'espace de nom "MathLib" avec une constante PI :
Math_file1.ts

namespace MathLib {
   export const PI:number = 3.14;
}
Le fichier Math_file2.ts définit l'espace de noms "MathLib" avec la fonction circleCircumference(radius) pour calculer la circonférence du cercle. Cette fonction utilise la constante PI définie dans le fichier Math_file1.ts.
Math_file2.ts

/// <reference path="./Math_file1.ts" />

namespace MathLib {
    export function circleCircumference(radius:number):number {
        // Use the PI constant defined in Math_file1.ts
        return 2 * PI * radius;
    }
}
Le fichier Math_file3.ts définit l'espace de noms "MathLib" avec la classe Circle et la fonction circleArea(radius). Ce fichier utilise les constantes et les fonctions définies dans les fichiers Math_file1.ts et Math_file2.ts.
Math_file3.ts

/// <reference path="./Math_file1.ts" />
/// <reference path="./Math_file2.ts" />

namespace MathLib {  
    export function circleArea(radius: number): number {
        // Use the PI constant defined in Math_file1.ts
        return PI * radius * radius;
    }
    export class Circle {
        radius : number;
        constructor(radius: number) {
            this.radius = radius;
        }
        getArea()  {
            return circleArea(this.radius);
        }
        getCircumference() {
            // Use the function defined in Math_file2.ts
            return circleCircumference(this.radius);
        }
    }
 }
Le fichier test.ts utilise l'espace de noms "MathLib".
test.ts

/// <reference path="./Math_file3.ts" />

let circle = new MathLib.Circle(100);

let area = circle.getArea();
let circumference  = circle.getCircumference();

console.log('area = ' + area);
console.log('circumference = ' + circumference);
Compiler tous les fichiers TypeScript dans des fichiers JavaScript :

tsc
Ensuite, utiliser le drapeau "--outFile" pour compiler le fichier test.ts et les bibliothèques qu'il utilise dans un seul fichier :

tsc --outFile ./dist/all_in_one.js test.ts
Après la compilation, on obtient le fichier JavaScript, qui devrait ressembler à ceci :
test.js

"use strict";
/// <reference path="./Math_file3.ts" />
let circle = new MathLib.Circle(100);
let area = circle.getArea();
let circumference = circle.getCircumference();
console.log('area = ' + area);
console.log('circumference = ' + circumference);
all_in_one.js

var MathLib;
(function (MathLib) {
    MathLib.PI = 3.14;
})(MathLib || (MathLib = {}));
/// <reference path="./Math_file1.ts" />
var MathLib;
(function (MathLib) {
    function circleCircumference(radius) {
        // Use the PI constant defined in Math_file1.ts
        return 2 * MathLib.PI * radius;
    }
    MathLib.circleCircumference = circleCircumference;
})(MathLib || (MathLib = {}));
/// <reference path="./Math_file1.ts" />
/// <reference path="./Math_file2.ts" />
var MathLib;
(function (MathLib) {
    function circleArea(radius) {
        // Use the PI constant defined in Math_file1.ts
        return MathLib.PI * radius * radius;
    }
    MathLib.circleArea = circleArea;
    var Circle = /** @class */ (function () {
        function Circle(radius) {
            this.radius = radius;
        }
        Circle.prototype.getArea = function () {
            return circleArea(this.radius);
        };
        Circle.prototype.getCircumference = function () {
            // Use the function defined in Math_file2.ts
            return MathLib.circleCircumference(this.radius);
        };
        return Circle;
    }());
    MathLib.Circle = Circle;
})(MathLib || (MathLib = {}));
/// <reference path="./Math_file3.ts" />
var circle = new MathLib.Circle(100);
var area = circle.getArea();
var circumference = circle.getCircumference();
console.log('area = ' + area);
console.log('circumference = ' + circumference);
Et exécuter cet exemple sur l'environnement NodeJS :

node ./dist/all_in_one.js
Pour exécuter l'exemple dans le navigateur, on créera le fichier test.html :
test.html

<html>
   <head>
      <script type="module" src="./dist/test.js"></script>
   </head>
   <body>
      <h3>To test, you need to run this file on an HTTP or HTTPS server.
         And see the results on the browser Console.
      </h3>
   </body>
</html>
Ce fichier test.html doit être exécuté sur un serveur HTTP ou HTTPS et afficher les résultats dans la fenêtre de la Console du navigateur.

4- Ambient Namespaces

  • TODO Link?