--- title: Typescript theme: ./_themes/5ika.css highlightTheme: github verticalSeparator: revealOptions: transition: 'fade' --- # TypeScript Du Javascript, mais typé *Tim Izzo - BDWA - Cours React* --- ## Qu'est-ce que TypeScript ? - TypeScript est un langage de programmation Open Source développé par Microsoft - C'est une sorte de surcouche à Javascript qui rend le langage **typé**. - 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. --- ## Avantages de TypeScript - **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. - **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. - **Meilleure maintenabilité :** Les fonctionnalités avancées de TS permettent une meilleure organisation et une meilleure maintenabilité du code. --- ## Installation de TypeScript Pour installer TypeScript, vous pouvez utiliser npm : ```bash npm install -g typescript ``` On peut ainsi utiliser la commande `tsc` qui peut convertir le Typescript en Javascript. Même si généralement, on utilise des outils qui s'occupent de cette conversion automatiquement. --- ## Exemple de code ```typescript function add(a: number, b: number): number { return a + b; } const resultA = add(2, 3); // Affiche une erreur dans l'IDE const resultB = add('lundi', 'mardi'); ``` > L'extension de fichier utilisée est `.ts` plutôt que `.js`. > `.tsx` plutôt que `.jsx`. --- ## Types de données Typescript TypeScript comprend plusieurs types de données prédéfinis, tels que number, string, boolean, object, etc. Voici quelques exemples : ```typescript let age: number = 25; let name: string = "John"; let isStudent: boolean = true; let person: object = { name: "John", age: 25 }; let weekdays: string[] = ["lundi", "jeudi", "samedi"]; ``` Il est également possible de définir des types personnalisés à l'aide des interfaces et des types. --- ## Interfaces en TypeScript Les interfaces sont utilisées pour définir des structures d'objet. Voici un exemple d'utilisation d'interfaces : ```typescript interface Person { name: string; age: number; greet: () => void; } const person: Person = { name: "John", age: 25, greet: () => { console.log(`Hello, my name is ${person.name}`); }, }; person.greet(); ``` --- ## Composant React Typescript nous permet notamment de typer les `props` des composants: ```typescript interface Props { posts: Post[]; getPost: (id: string) => void; } const PostsLists = (props: Props) => { const {posts, getPost} = props; return ... } ``` --- ## Hooks De même, on peut typer les states pour assurer un code consistant: ```typescript const Compo = () => { const [count, setCount] = useState(0); const [name, setName] = useState(''); const [profile, setProfile] = useState<{name: string, age: number}>(); // Cela affiche des erreurs: setCount({value:2}); setName(13); setProfile({firstname: 'Tim'}) } ``` --- ## Inférence Typescript est capable de faire de l'*inférence*. C'est à dire qu'il est capable parfois de deviner un type de variable sans qu'on ait besoin de lui indiquer. Par exemple avec les hooks: ```typescript const Compo = () => { const [count, setCount] = useState(0); // number const [name, setName] = useState('Tim'); // string const [profile, setProfile] = useState({age: 45, city: 'GE'}); // {age: number, city: string} const arr = [1, 'yop', profile]; // TS déduit que `arr` est de type // [number, string, {age: number, city: string}] } ``` --- ## Union Parfois, une variable peut avoir plusieurs types potentiels. On peut utiliser une *union* pour la définir: ```typescript let id: string | number = 10; id = '13'; // OK id = 13: // OK id = [11, 12]; // Pas OK ``` Pour déterminer dans notre code le type actuel d'une variable: ```typescript if(typeof id === 'string') console.log(`ID est un string`); else if(typeof id === 'number') console.log('ID est un nombre'); ``` --- Les interfaces peuvent avoir des propriétés facultatives qui ont le droit d'être `undefined`. On utilise pour ça le symbole `?`. ```typescript interface MyCompoProps { className?: string; isFocused?: boolean; style: object; } ``` --- ## Any Le type `any` est une triche qui permet de bypasser le système de type. Une variable de type `any` peut stocker tout type de données sans lever d'erreur. Son utilisation n'est pas recommandée et sert à des cas très particuliers. --- De plus en plus de libs sont écrites en Typescript, comme React. Cela permet notamment d'avoir de l'auto-complétion quand on développe et d'avoir une mini-doc toujours à disposition. Pour avoir les interfaces et types d'une lib externe, il est nécessaire de les télécharger séparemment. Par convention, ce sont des modules qui commencent par `@types/`. ```bash npm install --dev @types/react @types/react-dom ``` --- # Travail pratique 1 1. Initialiser un nouveau projet **Typescript** avec ViteJS 2. Créer un composant `Profile` et l'importer dans `App.tsx` 3. Typer l'objet *props* de Profile pour que le composant accepte les props suivantes: - `firstname` : string - `lastname`: string - `age`: number - `likedPages`: string[] 4. Dans `App.tsx`, fournir au composant Profile des props qui fonctionnent 5. Ajouter un peu de contenu JSX pour afficher les props dans la page --- # Travail pratique 2 1. Dans le composant `Profile`, ajouter un state `promotion`. 2. Faire en sorte que ce state soit typé pour accepter que les valeurs suivantes: `DEV7`, `DEV6`, `DEV5`. Il ne faut pas utiliser `string` comme type. 3. Ajouter un sélecteur dans le composant pour pouvoir sélectionner une promotion et adapter le state. 4. Trouver comment optimiser le code pour le rendre plus DRY. --- # À partir du travail réalisé - Dans `App.jsx`, que se passe-t-il quand vous ne fournissez pas une prop (par exemple `lastname`) ? - Dans `App.jsx`, que se passe-t-il quand vous fournissez `18ans` (string) comme prop `age` ? - Dans le composant `Profile`, que se passe-t-il dans VSCode, quand vous entrez `props.` puis CTRL+Espace ? - Dans votre navigateur, retrouvez où se trouve les informations de typage des props du composant `Profile`. --- ## Dans la pratique Au début, Typescript est plutôt contraignant. Il lève des erreurs partout et en tant que néophyte, on veut typer absolument tout. Ce n'est pas nécessaire de vouloir faire parfait dès le début. Installer Typescript en faisant du Javascript standard (dans des fichiers `.ts`) est déjà une bonne chose qui améliore le code. --- Vous avez maintenant les bases avec lesquelles on peut tout composer. Cela peut vite devenir complexe néanmoins. Pour aller plus loin => https://www.typescriptlang.org/docs/handbook/typescript-in-5-minutes.html --- # Exemples ## Fonction ```ts function greet(name: string): string { return `Hello, ${name}!`; } let greeting: string = greet("Bob"); console.log(greeting); // Output: Hello, Bob! ``` # Interface ```ts interface Person { firstName: string; lastName: string; age: number; } let user: Person = { firstName: "John", lastName: "Doe", age: 30 }; ``` # Union ```ts let code: string | number; code = 123; code = "ABC"; function displayCode(code: string | number) { console.log(code); } ``` # Alias ```ts type StringOrNumber = string | number; let value: StringOrNumber; value = "Hello"; value = 42; ``` # Types optionnels ```ts function buildName(firstName: string, lastName?: string): string { if (lastName) { return `${firstName} ${lastName}`; } else { return firstName; } } let result1 = buildName("Alice"); let result2 = buildName("Alice", "Smith"); ``` # Promise ```ts function fetchCharacters(ms: number): Promise { return axios.get('/api/characters'); } const charactersPromise = fetchCharacters(); const characters = await fetchCharacters(); ``` # Générique ```ts function identity(arg: T): T { return arg; } let output1 = identity("myString"); let output2 = identity(100); ```