Cours 04 - Principes de base de TypeScript
Table des matières
Objectifs
- Connaître le concept de typage de TypeScript
- Connaître les types que procure TypeScript
- Mettre en place l'infrastructure et comprendre l'utilité de TypeScript
Déroulement
- Introduction au cours
- Les types
- Atelier 04 - Utilisation des types
- Exercice 04 - Utilisation de TypeScript
- Conclusion
Les types
En plus des types de base de JavaScript, TypeScript permet de créer des types personnalisés (comme des objets) et d'utiliser des unions de types (où une variable peut être de l'un de plusieurs types), rendant le langage très flexible tout en gardant le code sûr et facile à comprendre.
Types en JavaScript :
number
: Représente à la fois les nombres entiers et les nombres à virgule flottante.string
: Utilisé pour représenter du texte sous forme de chaînes de caractères.boolean
: Peut prendre deux valeurs, vrai (true
) ou faux (false
).null
: Représente l'absence intentionnelle de toute valeur d'objet.undefined
: Indique qu'une variable n'a pas été initialisée et qu'aucune valeur lui a été attribuée.object
: Utilisé pour stocker des collections de données et des entités plus complexes.
Types ajoutés en TypeScript :
any
: Permet n'importe quelle valeur, offrant une échappatoire au système de typage.tuple
: Permet de représenter un tableau avec un nombre fixe d'éléments dont les types sont connus, mais pas nécessairement identiques.enum
: Permet de définir un ensemble de constantes nommées pour améliorer la lisibilité du code.unknown
: Semblable àany
, mais plus sûr car il nécessite une vérification de type avant de pouvoir être utilisé.never
: Représente le type de valeurs qui ne se produisent jamais (par exemple, une fonction qui lance une exception ou une fonction qui ne se termine jamais).
Liens utiles
- Javascript - Structures de données et types
- Les types de données
- TypeScript Special Types
- 10 astuces Typescript pour les développeurs débutants
Atelier 04 - Utilisation des types
Prérequis
Prenez le temps d'aller lire cette documentation, c'est la doc officielle et complète!
Partie 01 - Les types de base
Pour débuter l'atelier:
- Effacer le dossier node_modules et dist du dossier de l'atelier 03 (atel03)
- Faite une copie du dossier atel03 et renommez-le atel04
Dans le terminal, on installe les dépendances et on lance le serveur:
npm install
npm run dev
On retourne dans index.ts pour faire des tests
À la toute fin du script, ajoutez les lignes suivantes:
let ventes: number = 123456789 // possible d'écrire un nombre large comme suit: 123_456_789
let cours: string = "TypeScript"
let est_publie: boolean = true
let niveau
C'est possible d'enlever la déclaration de type ex:
let est_publie = true //La variable sera typée booléenne à cause du true
Si on passe notre curseur sur la variable niveau on voit son type (any)
- Ça veut dire n'importe quel type (attention à ne pas mettre any partout!)
On va écrire notre première fonction:
function render(document) {
console.log(document)
}
Il va y avoir une erreur car le type de document n'est pas spécifié!
Si on ne connais pas le type car c'est un gros projet on va devoir utiliser 'any':
function render(document: any) {
console.log(document)
}
Donc, any représente tous les types possibles!
Les tableaux en javascript:
let nombres = [1, 2, "3"] // c'est valide!
En TypeScript:
let nombres: number[] = [1, 2, "3"] // c'est pas valide!
let nombres: number[] = [1, 2, 3] // devient valide!
let nombres = [1, 2, 3] // fonctionne quand même comme un array de nombre!
Si on fait un tableau suivant:
let nombres = [] // son type sera any!
let nombres: number[] = [] // sera mieux et valide ici!
Maintenant, voici l’autocomplétion en TypeScript, si on écrit:
let nombres: number[] = []
nombres.forEach(n => n.)
On va voir ici la liste des méthodes qui appartiennent à number!
Vous pouvez effacer cet essai.
Type tuple, exemple:
let usager: [number, string] = [31, "MasterJim"]
Deux valeurs ici mais, on pourrait en mettre plus, mais ma recommandation pour du clean code (pas plus de deux!)
Type enum, exemple:
// const small = 1
// const medium = 2
// cont large = 3
enum Taille { Small = 1, Medium = 2, Large = 3}
// ou
enum Taille { Small = "s", Medium = "m", Large = "l"}
let maTaille: Taille = Taille.Large
si on utilise
const enum Taille { Small = 1, Medium = 2, Large = 3}
le code JavaScript sera plus optimal!
Les fonctions, exemples:
function calculerTaxe(montant: number): number {
return "a"
}
Ça va donner une erreur, à cause de la valeur de retour number!
Il y a aussi un warning de valeur non utilisée!
function calculerTaxe(montant: number): number {
return montant * 1.15
}
Ajouter un paramètre optionnel avec un ?
function calculerTaxe(montant: number, annee?: number): number {
if (annee < 2025)
return montant * 1.15
return montant * 1.3
}
calculerTaxe(10_000, 2026, 1) // erreur ici mais pas en javaScript!
calculerTaxe(10_000) // va donner une année undefined en TypeScript
Bonne fonction, avec valeur par défaut à 2024:
function calculerTaxe(montant: number, annee: number = 2024): number {
if (annee < 2025)
return montant * 1.15
return montant * 1.3
}
Les objets:
let employe:{
id: number,
nom: string
} = { id: 1, nom:"Jimmy Gilbert"}
Pour bloquer la modification d'une valeur, exemple l'id:
let employe:{
readonly id: number,
nom: string
} = { id: 1, nom:"Jimmy Gilbert"}
on pourra pas faire par la suite:
employe.id = 23 //donne une erreur
Si on veut ajouter la date de retraite sous forme de méthode:
let employe:{
readonly id: number,
nom: string,
retraite: (date: Date) => void
} = { id: 1, nom:"Jimmy Gilbert"}
retraite: (date: Date) => void
- le paramètre est date: Date et la valeur de retour est vide (void)
- ça ne va pas compiler, car on n'a pas donner la valeur de la méthode dans l'initialisation:
- { id: 1, nom:"Jimmy Gilbert"}
Pour l'ajouter:
let employe:{
readonly id: number,
nom: string,
retraite: (date: Date) => void
} = {
id: 1,
nom:"Jimmy Gilbert",
retraite: (date: Date) => {
console.log(date)
}
}
Partie 02 - Typage avancé
De retour à la fin de index.ts, on va faire d'autres tests
Alias de type
Si on reprend l'objet précédemment créé:
let employe: {
readonly id: number,
nom: string,
retraite: (date: Date) => void
} = {
id: 1,
nom: "Jimmy Gilbert",
retraite: (date: Date) => {
console.log(date)
}
}
Si on veut refaire un employé on doit refaire tout le code! DRY
Le code est aussi dur à lire...
On va créer un alias de type:
type Employe = {
readonly id: number,
nom: string,
retraite: (date: Date) => void
}
let employe: Employe = {
id: 1,
nom: "Jimmy Gilbert",
retraite: (date: Date) => {
console.log(date)
}
}
Le code est pas mal plus facile à lire et ajouter un employé est facile!!
Les unions de types permettent de donner deux types alternatifs à un paramètre dans une fonction
function kgToLbs(poids: number | string): number {
if (typeof poids === "number"){
return poids * 2.2
}else {
return parseInt(poids) * 2.2 //peut importe la veleur en string tant que le nombre est là!
}
}
console.log(kgToLbs(90))
console.log(kgToLbs("90kg"))
Les intersections de types permettent de donner deux types en même temps à un paramètre dans une fonction
Exemple pour un élément qui pourrait être déplacé à l'écran:
type Draggable = {
drag: () => void
}
type Resizable = {
resize: () => void
}
type UIWidget = Draggable & Resizable
let zoneTexte: UIWidget = {
drag: () => {},
resize: () => {}
}
Les types litéraux, exemple:
let quantite: number // peut être n'importe quel nombre
//Pour limiter les valeurs:
let quantite: 50 | 100 = 50 // 50 ou 100
//On peut utiliser des types!
type Quantite = 50 | 100
let quantite: Quantite = 100
//peut aussi être un string!
type Metrique = 'cm' | 'p'
Les types "null", permet d'utiliser des valeur de type null, mais on doit y penser avec des unions:
function message(nom: string | null){
if (nom) {
console.log("ALLO "+nom.toUpperCase+"!") // + pour concater en JS
} else {
console.log("ALLO!")
}
}
message(null) // | null permet d'envoyer une valeur nulle
message("Jimmy") // ça va être un string ici
Chaînage optionnel:
type Client = {
anniversaire: Date
}
function getClient(id: number): Client | null {
return id === 0 ? null : { anniversaire: new Date() }
}
let client = getClient(0)
console.log(client?.anniversaire) //va être éxécuté SEULEMENT si le client est défini et pas null
// va retourner undefined
let client = getClient(1)
console.log(client?.anniversaire) //va être éxécuté SEULEMENT si le client est défini et pas null
// va retourner la date
Aller plus loin encore!
type Client = {
anniversaire?: Date
}
function getClient(id: number): Client | null {
return id === 0 ? null : { anniversaire: new Date() }
}
let client = getClient(1)
console.log(client?.anniversaire?.fullYear()) //va être éxécuté SEULEMENT si le client est défini et pas null
// va retourner l'année seulement si la valeur est définie
Remise
Aucune remise pour cet atelier