Plan du site  
pixel
pixel

Articles - Étudiants SUPINFO

Premier pas avec TypeScript - Partie 2

Par Ramneek SINGH Publié le 13/08/2017 à 03:47:45 Noter cet article:
(0 votes)
Avis favorable du comité de lecture

Dans cet article nous allons aborder les concepts que nous n'avons pas pu aborder dans la première partie de cet article. Les concepts qui seront étudiés sont listés suivants :

  • Fonctions Surchargées

  • Côté Orienté Objet de TypeScript

  • Union Types

  • String literal Types

  • Type Aliases

  • Mixins

  • Générique

Fonctions surchargées

Nous avons déjà vu la syntaxe pour créer une fonction dans le TypeScript dans l'article précédent de cette série. Là nous allons voir comment créer des fonctions surchargées ce qui n'est pas possible de faire en JavaScript.

Une fonction surchargée est une fonction qui est définie plusieurs fois dans une application afin d’offrir différentes logiques à l’application. La seule chose à respecter lorsque nous définissons une fonction à plusieurs reprises est que le nom de la fonction doit être le même pour les fonctions qui redéfinissent la fonction originale mais ce concept n’a pas été totalement implémenté en TypeScript. Dans le TypeScript les fonctions surchargées ont certaines restrictions et une syntaxe unique comparée à d’autres langages qui autorisent le surchargement des fonctions.

function addition(a: number, b: number) : number
function addition(a: number, b: number, c: number) : number
function addition(a : number, b: number, c? : number) :number {
    if (c != undefined) {
        return a + b + c;
    } else {
        return a + b;
    }
}

addition(1, 5);
addition(1, 5, 9);

C'était un exemple des fonctions surchargées en TypeScript qui ne se rassemblent pas avec des fonctions surchargées dans d'autres langages de programmation. Dans l’exemple, la fonction est appelée addition qui a deux surcharges possibles pourtant nous avons défini 3 fois fonctions. Les deux premières surcharges sont symboliques et permet à TypeScript de vous présenter plusieurs options mais elles ne contiennent aucune définition ou corps propre à eux. La seule chose qui est unique est leur signature. La troisième fonction est la plus importante pour la définir correctement car il faut que ses paramètres soient compatibles avec les autres fonctions surchargées.

Dans les autres langages de programmations chaque version d’une fonction surchargée a son propre corps mais dans le TypeScript c’est impossible pour une raison simple qui est le code de TypeScript est écrit pour qu’il puisse se convertir en code JavaScript à un certain point mais la problématique est que JavaScript par définition n’autorise pas plusieurs fonctions utilisant le même nom. Si vous faites cela en TypeScript, le compilateur va mettre des messages d’erreurs malgré cela il va vous générer le code JavaScript qui aura deux fonctions portant le même nom. Dans ce cas-là JavaScript préfèrerait utiliser la deuxième fonction et la première sera ignorée. Dans le JavaScript si une fonction est définie plusieurs fois, JavaScript accepte la dernière définition de la fonction et les autres définitions sont ignorées. C'est pour cela aussi nous ne pouvons pas définir plusieurs définitions d'une fonction mais dans le TypeScript nous pouvons intégrer la logique de toutes les autres versions de la fonction surchargée. Comme nous l'avons fait dans l'exemple précédent.

Comment déterminer le type des donnés à retourner pour les fonctions surchargées ?

Pour déterminer le type à retourner, il suffit d'en considérer la liste suivante :

  • Si toutes les versions de la fonction surchargée renvoient le même type dans ce cas nous pouvons nous permettre de renvoyer ce type.

  • Si toutes les versions ne renvoient pas le même type dans ce cas il faudra renvoyer le type any.

Côté Orienté Objet de TypeScript

Si vous avez déjà travaillé avec un langage objet orienté dans ce cas-là vous pouvez sauter cette section et passer à la section suivante mais si jamais vous n’avez que travaillé avec JavaScript ou des langages procédurales je vous conseille de rester sur cette section.

Je vais survoler très rapidement ce concept car le but de cet article est de vous faire découvrir les concepts uniques à TypeScript et les technique avancées. Dans cette section je vais introduire :

  • Les classes et les objets

  • L’héritage

  • L’encapsulation

  • Les classes abstraites

  • Les interfaces

Les classes et les objets

Les classes, un concept très important dans les langages de programmation orienté objet. Dans le TypeScript, les classes sont aussi simples que d'autres langage de programmation orienté objets. Une classe représente la structure d'un objet et ses comportements. Dans le monde réel, chaque objet a des propriétés et des comportements. Par exemple, un objet c'est la voiture dont nous allons parler. Dans cet exemple, le nombre de chevaux et le nombre de portes de la voiture peuvent être considérés comme des propriétés et faire avancer et faire tourner la voiture peuvent être considéré comme des comportements de la voiture. La conversion de cet exemple en langage informatique va être ainsi :

  • les propriétés deviennent des attributs (dès fois aussi appelées des propriétés)

  • les comportements deviennent des méthodes ou des fonctions.

Donc une classe peut être instanciée (clonée) par des variables que nous appelons des objets. Voici un exemple représentant une classe de TypeScript :

class Voiture
{
   nombreDeChevaux : number;
   nombreDePortes: number;

   tourner(): void {
    // La logique
   }

   avancer(): void {
      //La logique
   }
}

Nous avons pris l'exemple d’une voiture et la convertir en une classe.

Note : Nous n’utilisons pas let ou var mot-clé let pour déclarer les variables dans une classe.

Instancier une classe

Instancier une classe est aussi simple que d'appeler une fonction. Nous allons nous servir de mot clé new pour créer un objet depuis une classe. Nous allons instancier un objet depuis la classe voiture que nous avons écrite au-dessus.

let voiture = new Voiture();

La variable voiture est désormais un objet qui est une instance de la classe Voiture. Et pour accéder aux attributs (variables) et méthodes (fonctions) de la classe nous allons suivre la même syntaxe que presque tous les langages de programmations orienté objet qui est instance.attribut ou instance.fonction().

voiture.nombreDeChevaux = 1000;
voiture.nombreDePortes = 5;
voiture.avancer();
voiture.tourner();
Constructeur

Un constructeur c’est une fonction void dénotée avec le mot-clé constructor qui est appelée par le compilateur lorsque nous créons un objet d’une classe. Dans l’exemple précédent nous avons déclaré une classe mais sans le constructeur. Lorsque nous déclarons une classe sans avoir déclaré son constructeur dans ce cas-là le constructeur est déclaré implicitement par le TypeScript mais ce constructeur ne prend aucun paramètre. Prenons le précédent exemple pour y rajouter un constructeur explicitement et mieux comprendre l’utilité d’un constructeur.

class Voiture
{
    constructor() {
          console.log("Je suis un constructeur");
    }

    // ....
}

let voiture = new Voiture();

Désormais lorsque nous créons des objets depuis cette classe le constructeur que nous avons déclaré explicitement sera automatiquement appelé par le compilateur et il fera exécuter le code qui se trouve dans le corps de constructeur. Donc, en l'occurrence cela va afficher Je suis un constructeur. De même manière nous pouvons insérer la logique que nous nous permettons de mettre dans une fonction standard. Comme une fonction un constructeur peut aussi prendre des paramètres mais il ne retourne que void c’est-à-dire rien.

Voici un exemple d’une classe dont le constructeur accepte un argument.

class Voiture
{
    nombreDeChevaux: number;
    constructor(nombreDeChevaux) {
        this.nombreDeChevaux = nombreDeCheavaux;
    }

    // ....
}

let voiture = new Voiture(500);

Il existe une autre façon de créer un constructeur qui prend des arguments tout en minimisant le nombre de lignes. Nous allons écrire le code au-dessus d’une manière plus concise.

class Voiture
{
    constructor(private nombreDeChevaux : number) {
    }

    // ....
}

let voiture = new Voiture(500);

Dans cet exemple nous avons déclaré la variable nombreDeChevaux dans le constructeur ainsi son niveau d’accessibilité, en l'occurrence, c’est private et le constructeur prends toujours un argument. Cela nous a fait retirer 2 lignes de code dont la première ligne est la déclaration de la variable nombreDeChevaux et seconde ligne était l’attribution d’une valeur à cette variable.

L’héritage

L’héritage permet à une classe d’inclure les propriétés (variables) héritables et les fonctions (méthodes) héritables d’une autre classe ce qui permet la réutilisation du code et évite la redondance du code. Dans l’exemple suivant nous allons créer un classe Vehicule dont la classe Voiture dérive.

class Vehicule
{
    nombreDeChevaux : number;
    getNombreDeChevaux() : number {
       return this.nombreDeChevaux;
    }
    setNombreDeChevaux(nombreDeChevaux: number): void {
        this.nombreDeChevaux = nombreDeChevaux;
    }
    tourner(): void {
        // La logique
    }

    avancer(): void {
        //La logique
    }
}
class Voiture extends Vehicule
{
    nombreDePortes: number;
    
    getNombreDePorte() : number {
        return this.nombreDePortes;
    }

    setNombreDePorte(nombreDePorte: number): void {
        this.nombreDePortes = nombreDePorte;
    }

}

let vehicule = new Vehicule();
vehicule.avancer();
let voiture = new Voiture();
voiture.avancer();

L’objet voiture fait appel à la fonction avancer pourtant elle n’est pas déclarée dans la classe Vehicule. C’est le mécanisme d’héritage qui a fait faire partager la classe Vehicule cette fonction ainsi que d’autres fonctions et des variables avec la classe dérivée. Par contre, la classe mère (celle qui est héritée) n’a pas accès aux variables et des fonctions de la classe dérivée.

L’encapsulation

Public, private et protected sont des mots-clés qui définissent niveau d'accessibilité des variables ou des fonctions qui se trouvent dans une classe. C'est là où JavaScript lague derrière TypeScript. Dans le JavaScript les variables et les fonctions sont déclarées public pourtant il y a des techniques pour rendres privées les attributs et les fonctions publique.

Public

Toutes les variables ou les fonctions qui sont déclarées sans avoir précisé leur niveau d'accessibilité sont par défaut déclarées en tant que des publics. Ils sont accessibles directement par les instances de la classe dont elles sont déclarées. Nous pouvons toujours préciser explicitement le niveau d’accès public.

Private

Les variables ou les fonctions déclarées private sont accessibles seulement par la classe elle-même dont elles sont déclarées. Les instances de cette classe n'ont pas accès direct aux variables et aux fonctions de la classe.

Protected

Protected est presque la même chose que private avec une exception c’est que les variables ou les fonctions qui sont déclarées protected sont aussi accessible par des classes qui héritent la classe dont elles sont déclarées.

Nous allons toujours continuer avec l’exemple de Vehicule et celui de Voiture.

class Vehicule
{
    private nombreDeChevaux: number;
    constructor(nombreDeChevaux: number) {
        this.nombreDeChevaux = nombreDeChevaux;
    }
    public getNombreDeChevaux(nombreDeChevaux: number) : number {
        return this.nombreDeChevaux;
    }
    protected tourner(): void {
       // La logique
    }

    protected  avancer(): void {
        //La logique
    }
}
class Voiture extends Vehicule
{
    public nombreDePortes: number;
    constructor(nombreDeChevaux: number, nombreDePortes: number) {
         super(nombreDeChevaux);
         this.nombreDePortes = nombreDePortes;
    }
    
    public getNombreDePorte() : number {
          return this.nombreDePortes;
    }

    public tournerEtAvancer(): void {
        super.tourner();
        super.avancer();
    }

}

let vehicule = new Vehicule(10);
let voiture = new Voiture(50,5);
voiture.tournerEtAvancer();

Dans l’exemple au-dessus la classe Voiture hérite de la classe Vehicule mais cette fois-ci elle n'hérite pas tout les attributs de la classe Vehicule. L’attribut nombreDeChevaux n’est pas accessible par la classe Voiture car il est marqué private. Et les deux fonctions de la classe Vehicule sont qu’accessibles par la classe elle-même et les classes qui lui héritent mais ces fonctions ne seront pas accessible par les instances des classes dérivées. Dans ces deux exemples, les constructeurs acceptent des arguments c’est pour cela au moment de la création des objets de ces classes nous avons passé des arguments pour les constructeurs.

Les classes abstraites

Les classes abstraites sont comme d'autres classes avec une exception près c’est qu'elles ne peuvent pas être instanciées, par contre elles peuvent être héritées par d'autres classes. En ajoutant le mot-clé abstract devant n'importe quelle classe la rend une classe abstraite. Les méthodes d'une classe abstraite peuvent être définies abstraites ou pas. La différence c'est que les méthodes marquées abstraites n'ont pas de corps premièrement et définissent juste la signature et obligent les classes dérivées de définir ces méthodes abstraites en tant que méthodes normales avec leurs corps.

abstract class Vehicule
{
    private nombreDeChevaux: number;
    constructor(nombreDeChevaux: number) {
        this.nombreDeChevaux = nombreDeChevaux;
    }
    public getNombreDeChevaux(nombreDeChevaux: number) : number {
        return this.nombreDeChevaux;
    }

    // La classe dérivée devra avoir ces deux fonctions car elles sont marquées abstraites
    abstract tourner(): void;
    abstract avancer(): void;
}
class Voiture extends Vehicule
{
    public nombreDePortes: number;

    constructor(nombreDeChevaux: number, nombreDePortes: number) {
        super(nombreDeChevaux);
        this.nombreDePortes = nombreDePortes;
    }
    
    public getNombreDePorte() : number {
        return this.nombreDePortes;
    }

    public tournerEtAvancer(): void {
        this.tourner();
        this.avancer();
    }

    public avancer(): void{
        
    }

    public tourner(): void{
        
    }

}

//let vehicule = new Vehicule(10);  // Cette ligne ne peut pas fonctionner
let voiture = new Voiture(50,5);
voiture.tournerEtAvancer();

Les interfaces

Il s'agit d'un contrat qu'une classe à respecter si elle l’implémente. Interface peut aussi contenir des propriétés non définies et des méthodes sans le corps comme les classes abstraites par contre le mot-clé abstract ne devrait pas être utilisé pour les signatures définies dans les interfaces.

interface IVehicule
{
    modele: string;
    getModele(): string;
}
abstract class Vehicule implements IVehicule
{
    private nombreDeChevaux: number;
    public modele: string;
    constructor(nombreDeChevaux: number) {
        this.nombreDeChevaux = nombreDeChevaux;
    }
    public getNombreDeChevaux(nombreDeChevaux: number) : number {
        return this.nombreDeChevaux;
    }

    public getModele(): string{
        return this.modele;
    }

    // La classe dérivée devra avoir ces deux fonctions car elles sont marquées abstraites
    abstract tourner(): void;
    abstract avancer(): void;
}
class Voiture extends Vehicule
{
    public nombreDePortes: number;

    constructor(nombreDeChevaux: number, nombreDePortes: number) {
        super(nombreDeChevaux);
        this.nombreDePortes = nombreDePortes;
    }
    
    public getNombreDePorte() : number {
        return this.nombreDePortes;
    }

    public tournerEtAvancer(): void {
        this.tourner();
        this.avancer();
    }

    public avancer(): void{
        
    }

    public tourner(): void{
        
    }

}

//let vehicule = new Vehicule(10);  // Cette ligne ne peut pas fonctionner
let voiture = new Voiture(50,5);
voiture.tournerEtAvancer();

Aller passons aux choses qui font distinguer TypeScript à d’autres langages de programmations !

Spread (REST parameter)

Spread ou REST paramètre est une technique qui peut être utilisée dans le cas où nous ne connaissons pas le nombre d'arguments qui sera envoyé à la fonction. Par principe, Une fonction JavaScript peut aussi recevoir d'arguments même si la fonction ne déclare pas explicitement le nombre d'arguments à recevoir. Mais avec TypeScript vous avez plus de contrôles sur le type d'argument à recevoir. Un paramètre spread est dénoté par trois points (...) qui se placent devant le nom de paramètre.

function addition (...chiffres : number[]) {
    let somme :number = 0;
    for (let chiffre of chiffres) {
        somme += chiffre;
    }
    return somme;
}

addition(2,5,9);
addition(1,5,9,99,5,36);

Dans le premier appel nous avons appelé la fonction avec 3 arguments alors que dans le deuxième appel nous avons passé 6 arguments à la fonction addition.

Deux autres types que je ne vous ai pas encore présenté qui peuvent être le type de paramètre d'une fonction qui sont des interfaces et des objets anonymes. Je vous les présenterai une fois que je vous aurai exposé le côté orienté objet de TypeScript.

Union Type

Union type simplement donne la possibilité de déclarer plusieurs types pour les variables et les fonctions. Il est dénoté par un trait vertical ou le pipe ( | ). Voici un cas où nous pouvons utiliser union type, admettons que nous avons un formulaire dans lequel nous avons un champ pour renseigner un code postale mais un code postal peut être numérique ou alphanumérique. Prenons l’exemple du code postal.

let codePostal: number = 75008;
codePostal = 75009;

Par contre ici nous ne pouvons pas définir un code postale alphanumérique. Union type opérateur va nous aider à faire cela.

let codePostale: number | string = 75008;
codePostal = "H1B";

Utilisons union type pour les fonctions :

class Rectangle {
    largeur: number;
    longeur: number;

}
class Cercle {
    rayon: number;
}

function aire(forme: Rectangle | Cercle) : number {
    if (forme instanceof Rectangle){
        return forme.largeur * forme.longeur;
    } else {
        return (forme.rayon * forme.rayon) * 3.14;
    }
}

Comme vous avez vu la fonction aire prend un argument qui peut être un objet de la classe Rectangle ou cercle. Dans un sens nous pouvons dire que union type remplace le type any car la fonction aire peut parfaitement prendre any comme un argument.

Type Alias

Comme le nom indique, Type Alias permet de créer des alias pour les types, les primitives, les unions, les tuples et les fonctions.

type numerique = number;
type alphNumerique = string;

function afficherCodePostale(codePostale: numerique | alphNumerique): void{
    if (typeof codePostale == "number") {
        console.log("Code postale passé est composé de chiifres");
    } else {
        console.log("Code postale passé est alphanumérique");
    }
}

String Literal Types

Il permet de définir les type alias avec des chaînes de caractères. Il nous évite faire des enums dans certains cas.

Type TypeVehicule = “train” | “bus” | “voiture” | “moto” | “avion”;

Let vehicule : TypeVehicule = “bus”;
Vehicule = “moto”;

Vehicule = “bateau”; //erreur 

Dans la première ligne nous avons attribué plusieurs valeurs au Type personnalisé appelé TypeVehicule. Les variables de ce type peuvent accepter une valeur parmi toutes les valeurs définies à ce type dans la première ligne. Dans la seconde ligne nous avons créé une variable vehicule de ce type personnalisé (TypeVehicule) et lui attribué “bus” qui est une valeur parmi les valeurs acceptables par ce type. Et dans la troisième ligne nous avons attribué à nouveau une autre valeur acceptable par ce type. Par contre dans la dernière ligne, le compilateur va afficher une erreur car la valeur attribuée à la variable ne fais pas partie de valeurs acceptables par le type de variable.

Mixins

C'est une possibilité pour intégrer les éléments d'une ou plusieurs classes dans une autre classe. Faire hériter une classe dérivée de plusieurs classes n'est pas encore possible mais avec des Mixins cela peut être plus ou moins faisable. Si vous avez déjà travaillé avec PHP, il y a de fortes chances que vous connaissez le concept de trait et si c’est le cas, les mixins sont quasiment la même chose que les traits.

class Moteur
{
    public anneeDeCreation: number;
    constructor(public constructeur: string, public nombreDePistons: number) {
    }

    getAnneeDeCreation(): number {
        return this.anneeDeCreation;
    }

    getConstructeur(): string{
        return this.constructeur;
    }

    getNombreDePistons(): number{
        return this.nombreDePistons;
    }
}

class TableauDeBord
{
    constructor(public compteTourMoteurNumerique: boolean, public tachymetreNumerique: boolean) { }

    estCompteTourMoteurNumerique(): boolean {
        return this.compteTourMoteurNumerique;
    }

    estTachymetreNumerique(): boolean {
        return this.tachymetreNumerique;
    }
}

class Voiture implements Moteur, TableauDeBord
{
    constructor(public modele : string, public anneeDeCreation: number, public constructeur: string, public nombreDePistons: number) { }

    public compteTourMoteurNumerique: boolean;
    public tachymetreNumerique: boolean;

    getAnneeDeCreation : () => 0;

    getConstructeur : () => "";

    getNombreDePistons: () => 0;

    estCompteTourMoteurNumerique: () => true;

    estTachymetreNumerique: () => true;

    getModele(): string {
        return this.modele;
    }
}

Dans l'exemple nous avons créé une class Moteur et une classe TableauDeBord qui ont leurs propres attributs et méthodes. La classe Voiture hérite de ces deux classes. A noter, la classe dérivée utilise le mot clé implements au lieu de extends. Pourtant c'est dit que le mot clé implements est utilisé pour implémenter des interfaces. Nous pouvons certainement traiter une classe comme une interface, il suffit juste de remplacer le mot clé extends par implements. Comme nous avons implémenter des classes en tant que des interfaces donc nous devons implémenter leurs attributs et leurs méthodes.

La question qui se pose est pour arriver au même résultat il aurait été mieux d'utiliser les interfaces plutôt que les mixins?

Oui, vous avez raison mais nous n’avons pas encore terminé il nous reste à créer une fonction magie qui va transformer l'inutilité en utilité. Voici la fonction :

function applyMixins(classeDerivee: any, classesMeres: any[]) {
    classesMeres.forEach(classeMere => {
        Object.getOwnPropertyNames(classeMere.prototype).forEach(name => {
            classeDerivee.prototype[name] = classeMere.prototype[name];
        });
    });
}

Que fait cette fonction ?

Tout simplement, cette fonction copie les corps des propriétés des classes mères vers la classe dérivée. Cette fonction a besoin d'être déclarée une seule fois dans votre application et surtout elle doit être accessible par tous les mixins existants dans votre application. Chaque mixin de votre application doit appeler cette fonction avant qu’il se rend utilisable.

Note : C’est une fonction comme les autres donc vous pouvez l’appeler comme vous voulez.

applyMixins(Voiture, [Moteur, TableauDeBord]);

let voiture = new Voiture("Phantom", 2017, "Royle Royce", 800);
console.log(voiture.getModele());
console.log(voiture.getAnneeDeCreation());
console.log(voiture.estTachymetreNumerique());

Dans la première ligne nous appelons la fonction qui est chargée de copier la logique. Puis nous créons un objet de la classe Voiture et nous appelons les méthodes de ce nouvel objet. La méthode getModele() et déclarée dans la classe Voiture cela ne devrait pas vous étonner mais les deux autres méthodes que nous avons appelé ne sont pas déclarées dans la classe Voiture pourtant elles fonctionnent comme elles le devraient.

Génériques

Générique est un concept ou un mécanisme qui permet d’éviter la redondance du code et de rendre votre application flexible. La réutilisabilité ou rendre son code utilisable plusieurs fois est un facteur très important à considérer dans une application. Le but du code générique est de se faire utiliser par plusieurs types et ne pas à se restreindre à un seul type. Les classes, les fonctions et les interfaces peuvent toutes être génériques.

Si vous avez déjà travaillé avec C#, C++ ou Java normalement vous devriez être familier avec ce concept.

Voici l'exemple d'une classe générique :

class Afficheur<T>
{
    constructor(private elements : T[]) {
    }

    afficher(): void{
        this.elements.forEach(e => console.log(e));
    }

    vider(): void {
        this.elements = [];
    }

    reinitialiser(elements: T[]): void{
        this.elements = elements;
    }
}


let entiersAfficheur = new Afficheur<number>([1, 2, 3]);
let motsAfficheur = new Afficheur<string>(["Bonjour", "Salut", "Au revoir"]);

entiersAfficheur.afficher();
motsAfficheur.afficher();

entiersAfficheur.vider();
motsAfficheur.vider();

entiersAfficheur.reinitialiser([5, 6, 7, 8]);
motsAfficheur.reinitialiser(["Hello", "Hi", "Bye"]);

entiersAfficheur.afficher();
motsAfficheur.afficher();

Voici un exemple d'une fonction générique :

function getTableau<T>(... elements : T[]): T[]{
    let array: T[] = elements;
    return array;
}

let tableauDeChiffres = getTableau<number>(1, 2, 5);

let tableauDeLettres = getTableau<string>("Hello", "Hi");

Conclusion

Ces deux articles étaient une brève introduction au TypeScript. Mon but était de vous présenter les bases de TypeScript ainsi que les fonctionnalités ou les concepts de niveau intermédiaire. En espérant que cela vous ouvre de nouvelles perspectives.

A propos de SUPINFO | Contacts & adresses | Enseigner à SUPINFO | Presse | Conditions d'utilisation & Copyright | Respect de la vie privée | Investir
Logo de la société Cisco, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société IBM, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Sun-Oracle, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Apple, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Sybase, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Novell, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Intel, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Accenture, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société SAP, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Prometric, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo de la société Toeic, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management Logo du IT Academy Program par Microsoft, partenaire pédagogique de SUPINFO, la Grande École de l'informatique, du numérique et du management

SUPINFO International University
Ecole d'Informatique - IT School
École Supérieure d'Informatique de Paris, leader en France
La Grande Ecole de l'informatique, du numérique et du management
Fondée en 1965, reconnue par l'État. Titre Bac+5 certifié au niveau I.
SUPINFO International University is globally operated by EDUCINVEST Belgium - Avenue Louise, 534 - 1050 Brussels