crea/react/Typescript.md (view raw)
1---
2title: Typescript
3theme: ./_themes/5ika.css
4highlightTheme: github
5verticalSeparator: <!--v-->
6revealOptions:
7 transition: 'fade'
8---
9
10
11# TypeScript
12Du Javascript, mais typé
13
14*Tim Izzo - BDWA - Cours React*
15
16---
17
18## Qu'est-ce que TypeScript ?
19
20- TypeScript est un langage de programmation Open Source développé par Microsoft
21- C'est une sorte de surcouche à Javascript qui rend le langage **typé**.
22- TypeScript est conçu pour améliorer le développement d'applications JavaScript à *grande échelle* en ajoutant des outils de vérification des types, d'autocomplétion et de refactorisation.
23
24---
25
26## Avantages de TypeScript
27
28- **Vérification des types :** TypeScript permet de détecter les erreurs de type **pendant la phase de développement**, dans l'IDE, ce qui facilite le débogage et rend le code plus robuste.
29- **Intellisense améliorée :** Grâce aux annotations de type, TypeScript offre une meilleure prise en charge de l'autocomplétion et de l'analyse statique du code dans les éditeurs de code.
30- **Meilleure maintenabilité :** Les fonctionnalités avancées de TS permettent une meilleure organisation et une meilleure maintenabilité du code.
31
32---
33
34## Installation de TypeScript
35
36Pour installer TypeScript, vous pouvez utiliser npm :
37
38```bash
39npm install -g typescript
40```
41
42On peut ainsi utiliser la commande `tsc` qui peut convertir le Typescript en Javascript.
43Même si généralement, on utilise des outils qui s'occupent de cette conversion automatiquement.
44
45---
46
47## Exemple de code
48
49```typescript
50function add(a: number, b: number): number {
51 return a + b;
52}
53
54const resultA = add(2, 3);
55
56// Affiche une erreur dans l'IDE
57const resultB = add('lundi', 'mardi');
58```
59
60> L'extension de fichier utilisée est `.ts` plutôt que `.js`.
61> `.tsx` plutôt que `.jsx`.
62
63---
64
65## Types de données Typescript
66
67TypeScript comprend plusieurs types de données prédéfinis, tels que number, string, boolean, object, etc.
68
69Voici quelques exemples :
70
71```typescript
72let age: number = 25;
73let name: string = "John";
74let isStudent: boolean = true;
75let person: object = { name: "John", age: 25 };
76let weekdays: string[] = ["lundi", "jeudi", "samedi"];
77```
78
79Il est également possible de définir des types personnalisés à l'aide des interfaces et des types.
80
81---
82
83## Interfaces en TypeScript
84
85Les interfaces sont utilisées pour définir des structures d'objet.
86
87Voici un exemple d'utilisation d'interfaces :
88
89```typescript
90interface Person {
91 name: string;
92 age: number;
93 greet: () => void;
94}
95
96const person: Person = {
97 name: "John",
98 age: 25,
99 greet: () => {
100 console.log(`Hello, my name is ${person.name}`);
101 },
102};
103
104person.greet();
105```
106
107---
108
109## Composant React
110
111Typescript nous permet notamment de typer les `props` des composants:
112
113```typescript
114interface Props {
115 posts: Post[];
116 getPost: (id: string) => void;
117}
118
119const PostsLists = (props: Props) => {
120 const {posts, getPost} = props;
121
122 return ...
123}
124```
125
126---
127
128## Hooks
129
130De même, on peut typer les states pour assurer un code consistant:
131
132```typescript
133const Compo = () => {
134 const [count, setCount] = useState<number>(0);
135 const [name, setName] = useState<string>('');
136 const [profile, setProfile] =
137 useState<{name: string, age: number}>();
138
139 // Cela affiche des erreurs:
140 setCount({value:2});
141 setName(13);
142 setProfile({firstname: 'Tim'})
143}
144```
145
146---
147
148## Inférence
149
150Typescript est capable de faire de l'*inférence*.
151C'est à dire qu'il est capable parfois de deviner un type de variable sans qu'on ait besoin
152de lui indiquer. Par exemple avec les hooks:
153
154```typescript
155const Compo = () => {
156 const [count, setCount] = useState(0); // number
157 const [name, setName] = useState('Tim'); // string
158 const [profile, setProfile] = useState({age: 45, city: 'GE'}); // {age: number, city: string}
159
160 const arr = [1, 'yop', profile];
161 // TS déduit que `arr` est de type
162 // [number, string, {age: number, city: string}]
163}
164```
165
166---
167
168## Union
169
170Parfois, une variable peut avoir plusieurs types potentiels.
171On peut utiliser une *union* pour la définir:
172
173```typescript
174let id: string | number = 10;
175
176id = '13'; // OK
177id = 13: // OK
178id = [11, 12]; // Pas OK
179```
180
181Pour déterminer dans notre code le type actuel d'une variable:
182
183```typescript
184if(typeof id === 'string') console.log(`ID est un string`);
185else if(typeof id === 'number') console.log('ID est un nombre');
186```
187
188---
189
190Les interfaces peuvent avoir des propriétés facultatives qui ont le droit
191d'être `undefined`.
192
193On utilise pour ça le symbole `?`.
194
195```typescript
196interface MyCompoProps {
197 className?: string;
198 isFocused?: boolean;
199 style: object;
200}
201```
202
203---
204
205## Any
206
207Le type `any` est une triche qui permet de bypasser le système de type.
208Une variable de type `any` peut stocker tout type de données sans
209lever d'erreur.
210
211Son utilisation n'est pas recommandée et sert à des cas très particuliers.
212
213---
214
215De plus en plus de libs sont écrites en Typescript, comme React.
216Cela permet notamment d'avoir de l'auto-complétion quand on développe
217et d'avoir une mini-doc toujours à disposition.
218
219Pour avoir les interfaces et types d'une lib externe, il est nécessaire
220de les télécharger séparemment. Par convention, ce sont des modules
221qui commencent par `@types/`.
222
223```bash
224npm install --dev @types/react @types/react-dom
225```
226
227---
228
229# Travail pratique 1
230
2311. Initialiser un nouveau projet **Typescript** avec ViteJS
2322. Créer un composant `Profile` et l'importer dans `App.tsx`
2333. Typer l'objet *props* de Profile pour que le composant accepte les props suivantes:
234 - `firstname` : string
235 - `lastname`: string
236 - `age`: number
237 - `likedPages`: string[]
2384. Dans `App.tsx`, fournir au composant Profile des props qui fonctionnent
2395. Ajouter un peu de contenu JSX pour afficher les props dans la page
240
241---
242
243# Travail pratique 2
244
2451. Dans le composant `Profile`, ajouter un state `promotion`.
2462. Faire en sorte que ce state soit typé pour accepter que les valeurs suivantes: `DEV7`, `DEV6`, `DEV5`.
247 Il ne faut pas utiliser `string` comme type.
2483. Ajouter un sélecteur dans le composant pour pouvoir sélectionner une promotion et adapter le state.
2494. Trouver comment optimiser le code pour le rendre plus DRY.
250
251---
252
253# À partir du travail réalisé
254
255- Dans `App.jsx`, que se passe-t-il quand vous ne fournissez pas une prop (par exemple `lastname`) ?
256- Dans `App.jsx`, que se passe-t-il quand vous fournissez `18ans` (string) comme prop `age` ?
257- Dans le composant `Profile`, que se passe-t-il dans VSCode, quand vous entrez `props.` puis CTRL+Espace ?
258- Dans votre navigateur, retrouvez où se trouve les informations de typage des props du composant `Profile`.
259
260---
261
262## Dans la pratique
263
264Au début, Typescript est plutôt contraignant.
265Il lève des erreurs partout et en tant que néophyte, on veut typer absolument
266tout.
267
268Ce n'est pas nécessaire de vouloir faire parfait dès le début.
269Installer Typescript en faisant du Javascript standard (dans des fichiers `.ts`)
270est déjà une bonne chose qui améliore le code.
271
272---
273
274Vous avez maintenant les bases avec lesquelles on peut tout composer.
275Cela peut vite devenir complexe néanmoins.
276
277Pour aller plus loin => https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes.html
278
279---
280
281# Exemples
282
283<!--v-->
284
285## Fonction
286
287```ts
288function greet(name: string): string {
289 return `Hello, ${name}!`;
290}
291
292let greeting: string = greet("Bob");
293console.log(greeting); // Output: Hello, Bob!
294```
295
296<!--v-->
297
298# Interface
299
300```ts
301interface Person {
302 firstName: string;
303 lastName: string;
304 age: number;
305}
306
307let user: Person = {
308 firstName: "John",
309 lastName: "Doe",
310 age: 30
311};
312```
313
314<!--v-->
315
316# Union
317
318```ts
319let code: string | number;
320code = 123;
321code = "ABC";
322
323function displayCode(code: string | number) {
324 console.log(code);
325}
326```
327
328<!--v-->
329
330# Alias
331
332```ts
333type StringOrNumber = string | number;
334
335let value: StringOrNumber;
336value = "Hello";
337value = 42;
338```
339
340<!--v-->
341
342# Types optionnels
343
344```ts
345function buildName(firstName: string, lastName?: string): string {
346 if (lastName) {
347 return `${firstName} ${lastName}`;
348 } else {
349 return firstName;
350 }
351}
352
353let result1 = buildName("Alice");
354let result2 = buildName("Alice", "Smith");
355```
356
357<!--v-->
358
359# Promise
360
361```ts
362function fetchCharacters(ms: number): Promise<Character[]> {
363 return axios.get('/api/characters');
364}
365
366const charactersPromise = fetchCharacters();
367const characters = await fetchCharacters();
368```
369
370<!--v-->
371
372# Générique
373
374```ts
375function identity<T>(arg: T): T {
376 return arg;
377}
378
379let output1 = identity<string>("myString");
380let output2 = identity<number>(100);
381```