GitHub repository:https://github.com/cheroliv/ts-codebase[ts-codebase, window="_blank]

Intro typescript

index.html

<!DOCTYPE html>
<html lang="fr">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
</head>

<body>
    Intro typescript
    <script src="01_types.js"></script>
    <script src="02_data_structure.js"></script>
    <script src="03_enums_tuples.js"></script>
</body>

</html>

Types in TypeScript

01_types.ts

/**
 * Les types en typescript
 */

//quand le type n'est pas defini des le debut,
// alors il est réassignable
// c'est le type Any qui est attribué par défaut
let my_var;
my_var = "username";
console.assert(my_var === "username");
my_var = 11;
console.assert(my_var === 11);
my_var = true;
console.assert(my_var === true);

let age = 1;
console.assert(age === 1);
age = 2;
// age="trois" c'est impossible
// car l'inference de type a attribué le type number
console.assert(age === 2);

// Déclaration explicite de type
let pi: Number = 3.14;
console.assert(typeof pi === "number");

Functions

Functions are reusable blocks of code.

Example of dimension:

const add = (a: number, b: number): number => a + b;

Data structure

02_data_structure.ts

/***
 * Structure de données:
 * Avec le type any on peut changer
 * le type de la variable à tout instruction
 * Lorsque l'on fixe le type
 * alors il n'est plus possible de le changer
 * lors d'une assignation
 */

// Arrays
let buddies: any[] = [
    "cheroliv",
    "imrandeh",
    "issoudeh",
    "soumi92"
]

console.assert(buddies[0] === "cheroliv");
console.assert(buddies[1] === "imrandeh");
console.assert(buddies[2] === "issoudeh");
console.assert(buddies[3] === "soumi92");
// Déclaré en type any, l'inference de type
// a bien réaligné en type string
console.assert(typeof buddies[0] === "string");
console.assert(typeof buddies[1] === "string");
console.assert(typeof buddies[2] === "string");
console.assert(typeof buddies[3] === "string");



let writers: (String | String | String | Number)[][] = [
    ["Chrétien", "de Troyes", "fr", 12],
    ["François", "Rabelais", "fr", 16],
    ["René", "Descartes", "fr", 17],
    ["Jean-Jacques", "Rousseau", "fr", 18],
    ["Georg", "Hegel", "de", 19],
    ["Karl", "Marx", "de", 19],
    ["Friedrich", "Engels", "de", 19],
    ["Victor", "Hugo", "fr", 19],
    ["Paul", "Verlaine", "fr", 19],
    ["Arthur", "Rimbaud", "fr", 19],
    ["Gérard", "de Nerval", "fr", 19],
    ["Georg", "Lukacs", "hu", 20],
    ["Franz", "Kafka", "hu", 20],
    ["Antonio", "Gramsci", "it", 20],
    ["Domenico","Losurdo","it",20],
];

// console.table(writers);


// Objects
let author: {
    first_name: String,
    last_name: String,
    lang: String,
    century: Number
} = {
    // slice(-1) renvoie le dernier élèment
    first_name: writers.slice(-1)[0][0] as String,
    last_name: writers.slice(-1)[0][1] as String,
    lang: writers.slice(-1)[0][2] as String,
    century: writers.slice(-1)[0][3] as Number,
}


// assertion sur la valeur en accés par encapsulation(dot)
console.assert(author.first_name === "Antonio")
console.assert(author.last_name === "Gramsci")
console.assert(author.lang === "it")
console.assert(author.century === 20);

// assertion sur le type en accès par index
console.assert(typeof author["first_name"] === "string")
console.assert(typeof author["last_name"] === "string")
console.assert(typeof author["lang"] === "string")
console.assert(typeof author["century"] === "number");

Enums and tuples

03_enums_tuples.ts

/**
 * Enums et Tuples
 *
 * Enum: il existe les enums numérique
 * et les enums chaine de caracteres.
 *
 * Tuple: similaire aux arrays mais ne peut
 * contenir qu'une valeur de type spécifié.
 *
 */

//Enum numérique
// l'index par de debut défaut est 0
// ici on le place a 1
enum Week {
    Monday = 1,
    Tuesday = 2,
    Wednesday = 3,
    Thursday = 4,
    Friday = 5,
    Saturday = 6,
    Sunday = 7,
};

console.assert(Week.Monday == 1);
console.assert(Week.Tuesday == 2);
console.assert(Week.Wednesday == 3);
console.assert(Week.Thursday == 4);
console.assert(Week.Friday == 5);
console.assert(Week.Saturday == 6);
console.assert(Week.Sunday == 7);

console.assert(Week[1] === "Monday");
console.assert(Week[2] === "Tuesday");
console.assert(Week[3] === "Wednesday");
console.assert(Week[4] === "Thursday");
console.assert(Week[5] === "Friday");
console.assert(Week[6] === "Saturday");
console.assert(Week[7] === "Sunday");

let motd_arr_fr: String[] = [
    "Associé à la Lune",
    "Du dieu Tiw, associé à Mars",
    "Du dieu germanique Odin",
    "Du dieu germanique du tonnerre Thor",
    "De la déesse germanique Frigga associée à Vénus",
    "Associé à Saturne",
    "Associé au Soleil",
];

let motd_arr_en: String[] = [
    "associated with the Moon",
    "from the god Tiw, associated with Mars",
    "from Germanic god Odin",
    "from Germanic god of thunder Thor",
    "from Germanic goddess Frigga associated with Venus",
    "associated with Saturn",
    "associated with the Sun",
];

// Un tuple (triple)
let monday_triple_fr: [
    Number,
    String,
    String
] = [
        Week.Monday,
        Week[Week.Monday],
        motd_arr_fr[0],
    ];


console.assert(monday_triple_fr[0] === 1);
console.assert(monday_triple_fr[1] === "Monday");
console.assert(monday_triple_fr[2] === "Associé à la Lune");


let monday_triple_en: [
    Number,
    String,
    String
] = [
        Week.Monday,
        Week[Week.Monday],
        motd_arr_en[0],
    ];

console.assert(monday_triple_en[0] === 1);
console.assert(monday_triple_en[1] === "Monday");
console.assert(monday_triple_en[2] === "associated with the Moon");


// On se fait un type pour ajouter le nom de la langue
type Meaning_of_the_day = {
    lang: String,
    meaning: (Week | String)[][],
};

//fonction d'affichage du type Meaning_of_the_day
const display_motd = (motd: Meaning_of_the_day) => {
    motd.meaning.forEach(day =>
        console.table(`${Week[day[0] as Week]}: ${day[1]}.(${motd.lang})`)
    )
};

//fonction d'assertion sur le type Meaning_of_the_day
// afin de verifier la concordance du contenu avec
// motd_arr_#lang#
const test_motd = (
    motd: Meaning_of_the_day,
    motd_arr: String[]
) => {
    console.assert(motd.lang.length === 2)
    for (const [i, value] of motd.meaning.entries()) {
        console.assert(value[1] === motd_arr[i]);
    }
};


let motd_fr: Meaning_of_the_day = {
    lang: "fr",
    meaning: [
        [Week.Monday, motd_arr_fr[0]],
        [Week.Tuesday, motd_arr_fr[1]],
        [Week.Wednesday, motd_arr_fr[2]],
        [Week.Thursday, motd_arr_fr[3]],
        [Week.Friday, motd_arr_fr[4]],
        [Week.Saturday, motd_arr_fr[5]],
        [Week.Sunday, motd_arr_fr[6]],
    ],
}

console.log("---------");
console.log("display_motd(motd_fr):");
display_motd(motd_fr);
test_motd(motd_fr, motd_arr_fr)


let motd_en: Meaning_of_the_day = {
    lang: "en",
    meaning: [
        [Week.Monday, motd_arr_en[0]],
        [Week.Tuesday, motd_arr_en[1]],
        [Week.Wednesday, motd_arr_en[2]],
        [Week.Thursday, motd_arr_en[3]],
        [Week.Friday, motd_arr_en[4]],
        [Week.Saturday, motd_arr_en[5]],
        [Week.Sunday, motd_arr_en[6]],
    ],
}

console.log("---------");
console.log("display_motd(motd_en):");
display_motd(motd_en);
console.log("---------");
test_motd(motd_en, motd_arr_en);

// Un tuple (triple) utilisant le type
// Meaning_of_the_day pour peupler le meaning
let motd_triple: [
    Number,
    String,
    String
] = [
        Week.Monday,
        Week[Week.Monday],
        motd_fr.meaning[0][1] as String
    ];

console.assert(motd_triple[0] === 1);
console.assert(motd_triple[1] === "Monday");
console.assert(motd_triple[2] === "Associé à la Lune");

Void and Never

04_void_never_types.ts

// Le type void est l'opposé du type any
// c'est l'absence de type.
function verify_writers_length(): void {
    console.assert(writers.length > 0);
}

verify_writers_length();

const verify_writers_length_arrow = (): void =>
    console.assert(writers.length > 0);

verify_writers_length_arrow();

//Type of et never
let value = 30;
console.assert(typeof value === "number");

//never: qqchs qui n'arrive jamais
function foo(x: String | Number): Boolean {
    if (typeof x === "string") {
        return true;
    } else if (typeof x === "number") {
        return false;
    }
    return fail("Error!")
}

function fail(message: String): never {
    throw new Error(message as string);
}

Classes and interfaces

04_void_never_types.ts

/**
 * Les classes:
 * members,
 * visibility,
 * nommage,
 * accesseurs
 * scope identifier: static,private,protected
 *
 * convention de nommage :
 * Les membres private sont préfixés avec un _ *
 */

class Member {
    username: String = "";
    email: String = "";
    private _password: String = "";
    readonly signup_date: Date = new Date(Date.now());

    constructor(username: String, email: String) {
        this.username = username;
        this.email = email;
    }

    get password(): String {
        return this._password;
    }

    set password(new_password: String) {
        this._password = new_password;
    }

    /**
     * Une fonction static qui initilise un member,
     * à partir d'un author
     */
    static fromAuthor(author: {
        first_name: String,
        last_name: String,
        lang: String,
        century: Number
    }): Member {
        return new Member(
            `${author.first_name}.${author.last_name}`,
            `${author.first_name}.${author.last_name}@acme.com`,
        );
    }
};


let domenico = Member.fromAuthor(author);
domenico.password = "test";

console.assert(domenico.email === "Domenico.Losurdo@acme.com");
console.assert(domenico.password === "test");


// Héritage
enum Forms {
    Undefined = 0,
    Polygones = 1,
    Circle = 2,
    Straight = 3,
    Segment = 4,
};

class Form {
    type: Forms = Forms.Undefined;
};

class Rectangle extends Form {
    h: Number = 0;
    w: Number = 0;
};

class Square extends Rectangle {
    side: Number = 0;
};


/**
 * Interface donne un contrat à un type.
 * Les interfaces permettent de définir la structure d'un objet.
 */

interface IPerson {
    username: String;
    email: String;
    readonly signup_date: Date;
}

const user1: IPerson = {
    username: Member.fromAuthor(author)["username"],
    email: Member.fromAuthor(author)["email"],
    signup_date: Member.fromAuthor(author)["signup_date"],
}

The tsconfig.json file

tsconfig.json

{
  /* Visit https://aka.ms/tsconfig to read more about this file */
  "compileOnSave": true,

  "compilerOptions": {
    "target": "es2016",
    "module": "CommonJS",
    "noEmitOnError": true,
    "strict": true,
    "noImplicitAny": true,
    "esModuleInterop": true
  }
}

Modules

Modules allow the code to be organized into multiple files.

Example of rating:

// Dans un fichier math.ts
export const add = (a: number, b: number): number => a + b;

// Dans un autre fichier
import { add } from './math';
let result = add(2, 3);

Promises

Promises are used to perform asynchronous operations.

Example of rating:

const promise = new Promise<string>((resolve) => {
    // Code asynchrone ici
    resolve("Succès");
});

promise.then((result) => {
    console.log(result);
});

async/await

async/await simplifies promise management.

Example of rating:

const fetchData = async (): Promise<void> => {
    const result = await someAsyncFunction();
    console.log(result);
};

Credits

Generics allow for the creation of reusable components with dynamic types.

Example of rating:

const identity = <T>(arg: T): T => arg;

const output = identity<string>("hello");
console.log(output);

Articles connexes