Typer des données simples

Typer des données

Nous l'avons brièvement vu avec quelques exemples dans les chapitres précédents : l'intérêt de TypeScript réside dans sa capacité à apporter un typage statique et à aider le développeur en signalant les erreurs à la compilation.

Variables

Vous pouvez ajouter un type à une variable :

const firstName: string = "Flo";
let bitcoins: number = 10000;
const isBlockchainEnthusiast: boolean = true;

TypeScript pourra de cette façon checker des éventuelles erreurs, comme ici :

const firstName: string = "Flo";
let bitcoins: number = 10000;

// génère une erreur
console.log(firstName - bitcoins);
src/demo.ts:5:13 - error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.
                                                                                                                                         
5 console.log(firstName - bitcoins);

Tableaux

const users: string[] = ['satoshi', 'vitalik', 'he yi'];
const userIds: number[] = [1, 2, 3];
const arr: any[] = [1, 2, 3, 'hello'];

Une autre syntaxe alternative :

const users: Array<string> = ['satoshi', 'vitalik', 'he yi'];
const userIds: Array<number> = [1, 2, 3];
const arr: Array<any> = [1, 2, 3, 'hello'];

Cette dernière syntaxe fait appel aux Generics mais nous verrons cette notion un peu plus tard.

Fonctions

Il est possible d'ajouter un type aux arguments des fonctions :

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

Et également un type pour le retour :

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

function greeting(): void {
    console.log("I love pizza!");
}

Ce qui est pratique pour anticiper des comportements inattendus :

// "5" + 0 donne 50 (les joies du JS...) mais heureusement TypeScript va détecter l'erreur
let res = addTwoNumbers("5", 0);
src/demo.ts:17:25 - error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
                                                                                                            
17 let res = addTwoNumbers("5", 0);

Objets

Il est également possible définir un type d'objet (façon anonyme) !

Dans une fonction :

function showUserBalance(user: {firstName: string, bitcoins: number}) {
    console.log(`${user.firstName} has ${user.bitcoins} BTC !!`);
}

showUserBalance({firstName: 'Flo', bitcoins: 10000 });

Pour une variable :

let user: { 
    firstName: string, 
    bitcoins: number 
} = { 
    firstName: 'Flo', 
    bitcoins: 10000 
}

Exemple (fonction et variable) :

let user: { 
    firstName: string, 
    bitcoins: number 
} = { 
    firstName: 'Flo', 
    bitcoins: 10000 
}

function showUserBalance(user: {firstName: string, bitcoins: number}) {
    console.log(`${user.firstName} has ${user.bitcoins} BTC !!`);
}

// ok
showUserBalance({firstName: 'Flo', bitcoins: 10000 });
showUserBalance(user);

// pas ok : eth n'est pas censé être défini
showUserBalance({firstName: 'Flo', bitcoins: 10000, eth: 100 });
// pas ok : manque bitcoins
showUserBalance({firstName: 'Flo'});

Propriétés optionnelles

On peut définir des propriétés optionnelles à l'aide du point d'interrogation : ?

Fonctions

function greeting(name: string, age?: number) {
    if(age) {
        console.log(`Hello ${name} you are ${age} years old!`);
    } else {
        console.log(`Hello ${name}!`);
    }
}

greeting('Flo', 9999);
// Hello Flo you are 9999 years old!

greeting('Flo');
// Hello Flo!

Objets

// ici lastName est optionnel
let user: {
    firstName: string,
    lastName?: string,
    bitcoins: number
} = {
    firstName: 'Flo',
    bitcoins: 10000
}

En JavaScript, si on essaye d'accéder à une propriété qui n'existe pas on obtient undefined : il faut donc bien faire attention quand on utilise les propriétés optionnelles et faire des vérifications !

Mais ne vous inquiétez pas, dans la majorité des cas, TypeScript va vous indiquer si vous avez oublié une vérification (avec le mode strict activé).

Safe navigation operator (?)

TypeScript possède un safe navigation operator qui permet d'accéder à une ou des propriétés d'un objet et dont on ne sait pas si elles seront présentes à l'avance, cela permet d'éviter d'avoir à multiplier le nombre de conditions (if/else) à utiliser.

Pour ce faire, vous devez utiliser le point d'interrogation : ?

Nous avons l'objet user suivant :

let user: {
    firstName: string,
    lastName?: string,
    bitcoins: number,
    nfts?: any[]
} = {
    firstName: 'Flo',
    bitcoins: 10000,
    nfts: [
        {
            id: 1,
            metadata: {
                name: 'CryptoPunk #1'
            }
        },
        {
            id: 2,
            metadata: {
                name: 'CryptoPunk #2'
            }
        },
    ]
}

Si on souhaite obtenir le nom du premier NFT de sa collection et le transformer en majuscule par exemple, il faudrait faire beaucoup de tests dans un if : l'user a-t-il au moins 1 NFT ? Est-ce que ce NFT a des metadata ? Si oui est-ce que la propriété name existe, etc.

Grâce au safe navigation operator on peut simplifier la syntaxe :

if(user.nfts) {
    const nftName = user.nfts[0]?.metadata?.name?.toUpperCase();
    console.log(nftName);
    // 'CryptoPunk #1'
}