Définition de TypeScript pour les projets React modernes à l'aide de Webpack
Publié: 2022-03-10En cette ère de développement de logiciels, JavaScript peut être utilisé pour développer presque n'importe quel type d'application. Cependant, le fait que JavaScript soit typé dynamiquement pourrait être une préoccupation pour la plupart des grandes entreprises, en raison de sa fonction de vérification de type lâche.
Heureusement, nous n'avons pas à attendre que le comité technique Ecma 39 introduise un système de type statique dans JavaScript. Nous pouvons utiliser TypeScript à la place.
JavaScript, étant typé dynamiquement, n'est pas conscient du type de données d'une variable tant que cette variable n'est pas instanciée au moment de l'exécution. Les développeurs qui écrivent de gros programmes logiciels peuvent avoir tendance à réaffecter une variable, déclarée précédemment, à une valeur d'un type différent, sans avertissement ni problème, ce qui entraîne des bogues souvent ignorés.
Dans ce didacticiel, nous apprendrons ce qu'est TypeScript et comment l'utiliser dans un projet React. À la fin, nous aurons construit un projet consistant en une application de sélection d'épisodes pour l'émission télévisée Money Heist , utilisant TypeScript et les crochets actuels de type React ( useState
, useEffect
, useReducer
, useContext
). Avec ces connaissances, vous pouvez continuer à expérimenter TypeScript dans vos propres projets.
Cet article n'est pas une introduction à TypeScript. Par conséquent, nous n'aborderons pas la syntaxe de base de TypeScript et JavaScript. Cependant, vous n'avez pas besoin d'être un expert dans l'une de ces langues pour suivre, car nous essaierons de suivre le principe KISS (restez simple, stupide).
Qu'est-ce que TypeScript ?
En 2019, TypeScript a été classé septième langage le plus utilisé et cinquième langage à la croissance la plus rapide sur GitHub. Mais qu'est-ce que TypeScript exactement ?
Selon la documentation officielle, TypeScript est un sur-ensemble typé de JavaScript qui se compile en JavaScript brut. Il est développé et maintenu par Microsoft et la communauté open source.
"Superset" dans ce contexte signifie que le langage contient toutes les caractéristiques et fonctionnalités de JavaScript et plus encore. TypeScript est un langage de script typé.
Il offre aux développeurs plus de contrôle sur leur base de code via ses annotations de type, ses classes et son interface, évitant aux développeurs d'avoir à corriger manuellement des bogues gênants dans la console.
TypeScript n'a pas été créé pour modifier JavaScript. Au lieu de cela, il développe JavaScript avec de nouvelles fonctionnalités précieuses. Tout programme écrit en JavaScript brut fonctionnera également comme prévu dans TypeScript, y compris les applications mobiles multiplateformes et les back-ends dans Node.js.
Cela signifie que vous pouvez également écrire des applications React en TypeScript, comme nous le ferons dans ce didacticiel.
Pourquoi TypeScript ?
Peut-être n'êtes-vous pas convaincu d'embrasser la bonté de TypeScript. Considérons quelques-uns de ses avantages.
Moins de bogues
Nous ne pouvons pas éliminer tous les bogues de notre code, mais nous pouvons les réduire. TypeScript vérifie les types au moment de la compilation et génère des erreurs si le type de variable change.
Pouvoir trouver ces erreurs évidentes mais fréquentes aussi tôt facilite grandement la gestion de votre code avec les types.
La refactorisation est plus facile
Vous voulez probablement souvent refactoriser pas mal de choses, mais parce qu'elles touchent tellement d'autres codes et beaucoup d'autres fichiers, vous hésitez à les modifier.
Dans TypeScript, de telles choses peuvent souvent être refactorisées d'un simple clic sur la commande "Renommer le symbole" dans votre environnement de développement intégré (IDE).

Dans un langage à typage dynamique tel que JavaScript, la seule façon de refactoriser plusieurs fichiers en même temps est d'utiliser la fonction traditionnelle de « rechercher et remplacer » à l'aide d'expressions régulières (RegExp).
Dans un langage à typage statique tel que TypeScript, "rechercher et remplacer" n'est plus nécessaire. Avec les commandes IDE telles que "Rechercher toutes les occurrences" et "Renommer le symbole", vous pouvez voir toutes les occurrences dans l'application de la fonction, de la classe ou de la propriété donnée d'une interface d'objet.
TypeScript vous aidera à trouver toutes les instances du bit refactorisé, à le renommer et à vous alerter avec une erreur de compilation au cas où votre code présenterait des incompatibilités de type après le refactoring.
TypeScript a encore plus d'avantages que ce que nous avons couvert ici.
Inconvénients de TypeScript
TypeScript n'est sûrement pas sans inconvénients, même compte tenu des fonctionnalités prometteuses soulignées ci-dessus.
Un faux sentiment de sécurité
La fonctionnalité de vérification de type de TypeScript crée souvent un faux sentiment de sécurité parmi les développeurs. La vérification de type nous avertit en effet lorsque quelque chose ne va pas avec notre code. Cependant, les types statiques ne réduisent pas la densité globale des bogues.
Par conséquent, la force de votre programme dépendra de votre utilisation de TypeScript, car les types sont écrits par le développeur et ne sont pas vérifiés au moment de l'exécution.
Si vous cherchez à TypeScript pour réduire vos bogues, veuillez plutôt envisager le développement piloté par les tests.
Système de saisie compliqué
Le système de saisie, bien qu'il soit un excellent outil à bien des égards, peut parfois être un peu compliqué. Cet inconvénient vient du fait qu'il est entièrement interopérable avec JavaScript, ce qui laisse encore plus de place à la complication.
Cependant, TypeScript est toujours JavaScript, il est donc important de comprendre JavaScript.
Quand utiliser TypeScript ?
Je vous conseille d'utiliser TypeScript dans les cas suivants :
- Si vous cherchez à créer une application qui sera maintenue sur une longue période , je vous recommande fortement de commencer par TypeScript, car il favorise l'auto-documentation du code, aidant ainsi les autres développeurs à comprendre facilement votre code lorsqu'ils rejoignent votre base de code. .
- Si vous avez besoin de créer une bibliothèque , envisagez de l'écrire en TypeScript. Cela aidera les éditeurs de code à suggérer les types appropriés aux développeurs qui utilisent votre bibliothèque.
Dans les dernières sections, nous avons équilibré les avantages et les inconvénients de TypeScript. Passons à l'affaire du jour : configurer TypeScript dans un projet React moderne .
Commencer
Il existe plusieurs façons de configurer TypeScript dans un projet React. Dans ce didacticiel, nous n'en couvrirons que deux.
Méthode 1 : créer une application React + TypeScript
Il y a environ deux ans, l'équipe React a publié Create React App 2.1, avec prise en charge de TypeScript. Ainsi, vous n'aurez peut-être jamais à faire de gros travaux pour intégrer TypeScript dans votre projet.

Pour démarrer un nouveau projet Create React App, vous pouvez exécuter ceci…
npx create-react-app my-app --folder-name
… ou ca:
yarn create react-app my-app --folder-name
Pour ajouter TypeScript à un projet Create React App, installez-le d'abord avec ses @types
respectifs :
npm install --save typescript @types/node @types/react @types/react-dom @types/jest
… ou:
yarn add typescript @types/node @types/react @types/react-dom @types/jest
Ensuite, renommez les fichiers (par exemple, index.js
en index.tsx
), et redémarrez votre serveur de développement !
C'était rapide, n'est-ce pas ?
Méthode 2 : configurer TypeScript avec Webpack
Webpack est un bundler de modules statiques pour les applications JavaScript. Il prend tout le code de votre application et le rend utilisable dans un navigateur Web. Les modules sont des morceaux de code réutilisables construits à partir des styles JavaScript, node_modules
, images et CSS de votre application, qui sont emballés pour être facilement utilisés sur votre site Web.
Créer un nouveau projet
Commençons par créer un nouveau répertoire pour notre projet :
mkdir react-webpack cd react-webpack
Nous allons utiliser npm pour initialiser notre projet :
npm init -y
La commande ci-dessus générera un fichier package.json
avec certaines valeurs par défaut. Ajoutons également quelques dépendances pour webpack, TypeScript et certains modules spécifiques à React.
Installation de packages
Enfin, nous devons installer les packages nécessaires. Ouvrez votre interface de ligne de commande (CLI) et exécutez ceci :
#Installing devDependencies npm install --save-dev @types/react @types/react-dom awesome-typescript-loader css-loader html-webpack-plugin mini-css-extract-plugin source-map-loader typescript webpack webpack-cli webpack-dev-server #installing Dependencies npm install react react-dom
Ajoutons également manuellement quelques fichiers et dossiers différents sous notre dossier react-webpack
:
- Ajoutez
webpack.config.js
pour ajouter des configurations liées au webpack. - Ajoutez
tsconfig.json
pour toutes nos configurations TypeScript. - Ajoutez un nouveau répertoire,
src
. - Créez un nouveau répertoire,
components
, dans le dossiersrc
. - Enfin, ajoutez
index.html
,App.tsx
etindex.tsx
dans le dossier descomponents
.
Structure du projet
Ainsi, notre structure de dossiers ressemblera à ceci :
├── package.json ├── package-lock.json ├── tsconfig.json ├── webpack.config.js ├── .gitignore └── src └──components ├── App.tsx ├── index.tsx ├── index.html
Commencez à ajouter du code
Nous allons commencer par index.html
:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>React-Webpack Setup</title> </head> <body> <div></div> </body> </html>
Cela créera le HTML, avec un div
vide avec un ID de output
.
Ajoutons le code à notre composant React App.tsx
:
import * as React from "react"; export interface HelloWorldProps { userName: string; lang: string; } export const App = (props: HelloWorldProps) => ( <h1> Hi {props.userName} from React! Welcome to {props.lang}! </h1> );
Nous avons créé un objet d'interface et l'avons nommé HelloWorldProps
, avec userName
et lang
ayant un type de string
.
Nous avons transmis props
à notre composant App
et l'avons exporté.
Maintenant, mettons à jour le code dans index.tsx
:
import * as React from "react"; import * as ReactDOM from "react-dom"; import { App } from "./App"; ReactDOM.render( <App userName="Beveloper" lang="TypeScript" />, document.getElementById("output") );
Nous venons d'importer le composant App
dans index.tsx
. Lorsque webpack voit un fichier avec l'extension .ts
ou .tsx
, il transpile ce fichier à l'aide de la bibliothèque awesome-typescript-loader.
Configuration TypeScript
Nous ajouterons ensuite une configuration à tsconfig.json
:
{ "compilerOptions": { "jsx": "react", "module": "commonjs", "noImplicitAny": true, "outDir": "./build/", "preserveConstEnums": true, "removeComments": true, "sourceMap": true, "target": "es5" }, "include": [ "src/components/index.tsx" ] }
Regardons également les différentes options que nous avons ajoutées à tsconfig.json
:
-
compilerOptions
Représente les différentes options du compilateur. -
jsx:react
Ajoute la prise en charge de JSX dans les fichiers.tsx
. -
lib
Ajoute une liste de fichiers de bibliothèque à la compilation (par exemple, l'utilisationes2015
nous permet d'utiliser la syntaxe ECMAScript 6). -
module
Génère le code du module. -
noImplicitAny
des erreurs pour les déclarations avec un typeany
implicite. -
outDir
Représente le répertoire de sortie. -
sourceMap
Génère un fichier.map
, qui peut être très utile pour déboguer l'application. -
target
Représente la version ECMAScript cible vers laquelle transpiler notre code (nous pouvons ajouter une version en fonction des exigences spécifiques de notre navigateur). -
include
Utilisé pour spécifier la liste de fichiers à inclure.
Configuration Webpack
Ajoutons une configuration de webpack à webpack.config.js
.
const path = require("path"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); module.exports = { entry: "./src/components/index.tsx", target: "web", mode: "development", output: { path: path.resolve(\__dirname, "build"), filename: "bundle.js", }, resolve: { extensions: [".js", ".jsx", ".json", ".ts", ".tsx"], }, module: { rules: [ { test: /\.(ts|tsx)$/, loader: "awesome-typescript-loader", }, { enforce: "pre", test: /\.js$/, loader: "source-map-loader", }, { test: /\.css$/, loader: "css-loader", }, ], }, plugins: [ new HtmlWebpackPlugin({ template: path.resolve(\__dirname, "src", "components", "index.html"), }), new MiniCssExtractPlugin({ filename: "./src/yourfile.css", }), ], };
Regardons les différentes options que nous avons ajoutées à webpack.config.js
:
-
entry
Ceci spécifie le point d'entrée pour notre application. Il peut s'agir d'un fichier unique ou d'un tableau de fichiers que nous souhaitons inclure dans notre build. -
output
Ceci contient la configuration de sortie. L'application examine cela lorsqu'elle essaie de sortir du code groupé de notre projet sur le disque. Le chemin représente le répertoire de sortie pour le code à sortir, et le nom du fichier représente le nom du fichier pour le même. Il est généralement nommébundle.js
. -
resolve
Webpack examine cet attribut pour décider de regrouper ou d'ignorer le fichier. Ainsi, dans notre projet, webpack considérera les fichiers avec les extensions.js
,.jsx
,.json
,.ts
et.tsx
pour le regroupement. -
module
Nous pouvons permettre à webpack de charger un fichier particulier à la demande de l'application, à l'aide de chargeurs. Il prend un objet rules qui spécifie que :- tout fichier qui se termine par l'extension
.tsx
ou.ts
doit utiliserawesome-typescript-loader
pour être chargé ; - les fichiers qui se terminent par l'extension
.js
doivent être chargés avecsource-map-loader
; - les fichiers qui se terminent par l'
.css
doivent être chargés aveccss-loader
.
- tout fichier qui se termine par l'extension
-
plugins
Webpack a ses propres limites, et il fournit des plugins pour les surmonter et étendre ses capacités. Par exemple,html-webpack-plugin
crée un fichier de modèle qui est rendu au navigateur à partir du fichierindex.html
dans le répertoire./src/component/index.html
.
MiniCssExtractPlugin
rend le fichier CSS
parent de l'application.
Ajout de scripts à package.json
Nous pouvons ajouter différents scripts pour créer des applications React dans notre fichier package.json
:
"scripts": { "start": "webpack-dev-server --open", "build": "webpack" },
Maintenant, exécutez npm start
dans votre CLI. Si tout s'est bien passé, vous devriez voir ceci :

Si vous avez un talent pour le webpack, clonez le référentiel pour cette configuration et utilisez-le dans vos projets.
Création de fichiers
Créez un dossier src
et un fichier index.tsx
. Ce sera le fichier de base qui rend React.
Maintenant, si nous npm start
, il exécutera notre serveur et ouvrira un nouvel onglet. L'exécution npm run build
créera un pack Web pour la production et créera un dossier de construction pour nous.
Nous avons vu comment configurer TypeScript à partir de zéro en utilisant la méthode de configuration Create React App et webpack.
L'un des moyens les plus rapides de maîtriser pleinement TypeScript consiste à convertir l'un de vos projets Vanilla React existants en TypeScript. Malheureusement, l'adoption progressive de TypeScript dans un projet vanilla React existant est stressante car elle implique d'éjecter ou de renommer tous les fichiers, ce qui entraînerait des conflits et une demande d'extraction géante si le projet appartenait à une grande équipe.
Ensuite, nous verrons comment migrer facilement un projet React vers TypeScript.
Migrer une application Create React existante vers TypeScript
Pour rendre ce processus plus gérable, nous le décomposerons en étapes, ce qui nous permettra de migrer en morceaux individuels. Voici les étapes que nous allons suivre pour migrer notre projet :
- Ajoutez TypeScript et les types.
- Ajoutez
tsconfig.json
. - Commencer petit.
- Renommez l'extension des fichiers en
.tsx
.
1. Ajouter TypeScript au projet
Tout d'abord, nous devrons ajouter TypeScript à notre projet. En supposant que votre projet React a été démarré avec Create React App, nous pouvons exécuter ce qui suit :
# Using npm npm install --save typescript @types/node @types/react @types/react-dom @types/jest # Using Yarn yarn add typescript @types/node @types/react @types/react-dom @types/jest
Notez que nous n'avons encore rien changé à TypeScript. Si nous exécutons la commande pour démarrer le projet localement ( npm start
ou yarn start
), rien ne change. Si c'est le cas, alors super ! Nous sommes prêts pour la prochaine étape.
2. Ajoutez le fichier tsconfig.json
Avant de profiter de TypeScript, nous devons le configurer via le fichier tsconfig.json
. Le moyen le plus simple de commencer est d'en échafauder un à l'aide de cette commande :
npx tsc --init
Cela nous donne quelques bases, avec beaucoup de code commenté. Maintenant, remplacez tout le code dans tsconfig.json
par ceci :
{ "compilerOptions": { "jsx": "react", "module": "commonjs", "noImplicitAny": true, "outDir": "./build/", "preserveConstEnums": true, "removeComments": true, "sourceMap": true, "target": "es5" }, "include": [ "./src/**/**/\*" ] }
Configuration TypeScript
Regardons également les différentes options que nous avons ajoutées à tsconfig.json
:
-
compilerOptions
Représente les différentes options du compilateur.-
target
Traduit les nouvelles constructions JavaScript vers une version plus ancienne, comme ECMAScript 5. -
lib
Ajoute une liste de fichiers de bibliothèque à la compilation (par exemple, l'utilisation de es2015 nous permet d'utiliser la syntaxe ECMAScript 6). -
jsx:react
Ajoute la prise en charge de JSX dans les fichiers.tsx
. -
lib
Ajoute une liste de fichiers de bibliothèque à la compilation (par exemple, l'utilisation de es2015 nous permet d'utiliser la syntaxe ECMAScript 6). -
module
Génère le code du module. -
noImplicitAny
Utilisé pour générer des erreurs pour les déclarations avec un typeany
implicite. -
outDir
Représente le répertoire de sortie. -
sourceMap
Génère un fichier.map
, qui peut être très utile pour déboguer notre application. -
include
Utilisé pour spécifier la liste de fichiers à inclure.
-
Les options de configuration varient en fonction de la demande d'un projet. Vous devrez peut-être consulter la feuille de calcul des options TypeScript pour déterminer ce qui conviendrait à votre projet.
Nous avons seulement pris les mesures nécessaires pour que les choses soient prêtes. Notre prochaine étape consiste à migrer un fichier vers TypeScript.
3. Commencez avec un composant simple
Profitez de la capacité de TypeScript à être progressivement adopté. Allez un fichier à la fois à votre propre rythme. Faites ce qui a du sens pour vous et votre équipe. N'essayez pas de tout aborder d'un coup.
Pour convertir correctement cela, nous devons faire deux choses :
- Modifiez l'extension de fichier en
.tsx
. - Ajoutez l'annotation de type (ce qui nécessiterait des connaissances en TypeScript).
4.Renommer les extensions de fichier en .tsx
Dans une grande base de code, il peut sembler fatigant de renommer les fichiers individuellement.
Renommer plusieurs fichiers sur macOS
Renommer plusieurs fichiers peut être une perte de temps. Voici comment vous pouvez le faire sur un Mac. Faites un clic droit (ou Ctrl
+ clic, ou cliquez avec deux doigts simultanément sur le trackpad si vous utilisez un MacBook) sur le dossier contenant les fichiers que vous souhaitez renommer. Ensuite, cliquez sur "Révéler dans le Finder". Dans le Finder, sélectionnez tous les fichiers que vous souhaitez renommer. Cliquez avec le bouton droit sur les fichiers sélectionnés et choisissez "Renommer les éléments X...". Ensuite, vous verrez quelque chose comme ceci :

Insérez la chaîne que vous souhaitez rechercher et la chaîne par laquelle vous souhaitez remplacer cette chaîne trouvée, puis appuyez sur "Renommer". Terminé.
Renommer plusieurs fichiers sous Windows
Renommer plusieurs fichiers sous Windows dépasse le cadre de ce didacticiel, mais un guide complet est disponible. Vous obtiendrez généralement des erreurs après avoir renommé les fichiers ; il vous suffit d'ajouter les annotations de type. Vous pouvez approfondir cela dans la documentation.
Nous avons expliqué comment configurer TypeScript dans une application React. Maintenant, construisons une application de sélection d'épisodes pour Money Heist en utilisant TypeScript.
Nous ne couvrirons pas les types de base de TypeScript. Il est nécessaire de parcourir la documentation avant de continuer dans ce didacticiel.
Il est temps de construire
Pour que ce processus soit moins intimidant, nous le décomposerons en étapes, ce qui nous permettra de créer l'application en morceaux individuels. Voici toutes les étapes que nous allons suivre pour créer le sélecteur d'épisodes de Money Heist :
- Échafaudez une application Create React.
- Récupérer des épisodes.
- Créez les types et interfaces appropriés pour nos épisodes dans
interface.ts
. - Configurez le magasin pour récupérer les épisodes dans
store.tsx
. - Créez l'action pour récupérer les épisodes dans
action.ts
. - Créez un composant
EpisodeList.tsx
les épisodes récupérés. - Importez le composant
EpisodesList
sur notre page d'accueil en utilisantReact Lazy and Suspense
.
- Créez les types et interfaces appropriés pour nos épisodes dans
- Ajouter des épisodes.
- Configurez le magasin pour ajouter des épisodes dans
store.tsx
. - Créez l'action pour ajouter des épisodes dans
action.ts
.
- Configurez le magasin pour ajouter des épisodes dans
- Supprimer des épisodes.
- Configurez le magasin pour supprimer des épisodes dans
store.tsx
. - Créez l'action de suppression d'épisodes dans
action.ts
.
- Configurez le magasin pour supprimer des épisodes dans
- Épisode préféré.
- Importer le composant
EpisodesList
dans l'épisode favori. - Render
EpisodesList
à l'intérieur de l'épisode préféré.
- Importer le composant
- Utilisation du routeur Reach pour la navigation.
Configurer React
Le moyen le plus simple de configurer React consiste à utiliser Create React App. Create React App est un moyen officiellement pris en charge pour créer des applications React d'une seule page. Il offre une configuration de construction moderne sans configuration.
Nous l'utiliserons pour amorcer l'application que nous allons construire. Depuis votre CLI, exécutez la commande ci-dessous :
npx create-react-app react-ts-app && cd react-ts-app
Une fois l'installation réussie, démarrez le serveur React en exécutant npm start
.

Comprendre les interfaces et les types dans Typescript
Les interfaces dans TypeScript sont utilisées lorsque nous devons donner des types aux propriétés des objets. Par conséquent, nous utiliserions des interfaces pour définir nos types.
interface Employee { name: string, role: string salary: number } const bestEmployee: Employee= { name: 'John Doe', role: 'IOS Developer', salary: '$8500' //notice we are using a string }
Lors de la compilation du code ci-dessus, nous verrions cette erreur : « Les types de salary
de propriété sont incompatibles. La string
de type n'est pas attribuable au type number
.”
De telles erreurs se produisent dans TypeScript lorsqu'une propriété ou une variable se voit attribuer un type autre que le type défini. Plus précisément, l'extrait de code ci-dessus signifie que la propriété de salary
a été affectée à un type de string
au lieu d'un type de number
.
Créons un fichier interface.ts
dans notre dossier src
. Copiez et collez-y ce code :
/** |-------------------------------------------------- | All the interfaces! |-------------------------------------------------- */ export interface IEpisode { airdate: string airstamp: string airtime: string id: number image: { medium: string; original: string } name: string number: number runtime: number season: number summary: string url: string } export interface IState { episodes: Array<IEpisode> favourites: Array<IEpisode> } export interface IAction { type: string payload: Array<IEpisode> | any } export type Dispatch = React.Dispatch<IAction> export type FavAction = ( state: IState, dispatch: Dispatch, episode: IEpisode ) => IAction export interface IEpisodeProps { episodes: Array<IEpisode> store: { state: IState; dispatch: Dispatch } toggleFavAction: FavAction favourites: Array<IEpisode> } export interface IProps { episodes: Array<IEpisode> store: { state: IState; dispatch: Dispatch } toggleFavAction: FavAction favourites: Array<IEpisode> }
C'est une bonne pratique d'ajouter un "I" au nom de l'interface. Cela rend le code lisible. Cependant, vous pouvez décider de l'exclure.
Interface d'épisode
Notre API renvoie un ensemble de propriétés telles que airdate
, airstamp
, airtime
, id
, image
, name
, number
, runtime
, season
, summary
et url
. Par conséquent, nous avons défini une interface IEpisode
et défini les types de données appropriés sur les propriétés de l'objet.
Interface IState
Notre interface IState
a respectivement des propriétés d' episodes
et de favorites
, et une interface Array<IEpisode>
.
IAction
Les propriétés de l'interface IAction
sont payload
et type
. La propriété type
a un type chaîne, tandis que la charge utile a un type Array | any
Array | any
.
Notez que Array | any
Array | any
signifie un tableau de l'interface de l'épisode ou n'importe quel type.
Le type Dispatch
est défini sur React.Dispatch
et une interface <IAction>
. Notez que React.Dispatch
est le type standard de la fonction dispatch
, selon la base de code @types/react
react, tandis que <IAction>
est un tableau de l'action Interface.

En outre, Visual Studio Code dispose d'un vérificateur TypeScript. Ainsi, en mettant simplement en surbrillance ou en survolant le code, il est assez intelligent pour suggérer le type approprié.
En d'autres termes, pour que nous puissions utiliser notre interface dans nos applications, nous devons l'exporter. Jusqu'à présent, nous avons notre magasin et nos interfaces qui contiennent le type de notre objet. Créons maintenant notre boutique. Notez que les autres interfaces suivent les mêmes conventions que celles expliquées.
Récupérer des épisodes
Création d'un magasin
Pour récupérer nos épisodes, nous avons besoin d'un magasin qui contient l'état initial des données et qui définit notre fonction de réduction.
Nous utiliserons le crochet useReducer
pour configurer cela. Créez un fichier store.tsx
dans votre dossier src
. Copiez et collez-y le code suivant.
import React, { useReducer, createContext } from 'react' import { IState, IAction } from './types/interfaces' const initialState: IState = { episodes: [], favourites: [] } export const Store = createContext (initialState) const reducer = (state: IState, action: IAction): IState => { switch (action.type) { case 'FETCH_DATA': return { ...state, episodes: action.payload } default: return state } } export const StoreProvider = ({ children }: JSX.ElementChildrenAttribute): JSX.Element => { const [state, dispatch] = useReducer(reducer, initialState) return {children} }
import React, { useReducer, createContext } from 'react' import { IState, IAction } from './types/interfaces' const initialState: IState = { episodes: [], favourites: [] } export const Store = createContext (initialState) const reducer = (state: IState, action: IAction): IState => { switch (action.type) { case 'FETCH_DATA': return { ...state, episodes: action.payload } default: return state } } export const StoreProvider = ({ children }: JSX.ElementChildrenAttribute): JSX.Element => { const [state, dispatch] = useReducer(reducer, initialState) return {children} }
import React, { useReducer, createContext } from 'react' import { IState, IAction } from './types/interfaces' const initialState: IState = { episodes: [], favourites: [] } export const Store = createContext (initialState) const reducer = (state: IState, action: IAction): IState => { switch (action.type) { case 'FETCH_DATA': return { ...state, episodes: action.payload } default: return state } } export const StoreProvider = ({ children }: JSX.ElementChildrenAttribute): JSX.Element => { const [state, dispatch] = useReducer(reducer, initialState) return {children} }
import React, { useReducer, createContext } from 'react' import { IState, IAction } from './types/interfaces' const initialState: IState = { episodes: [], favourites: [] } export const Store = createContext (initialState) const reducer = (state: IState, action: IAction): IState => { switch (action.type) { case 'FETCH_DATA': return { ...state, episodes: action.payload } default: return state } } export const StoreProvider = ({ children }: JSX.ElementChildrenAttribute): JSX.Element => { const [state, dispatch] = useReducer(reducer, initialState) return {children} }
Voici les étapes que nous avons suivies pour créer le magasin :
- Pour définir notre magasin, nous avons besoin du hook
useReducer
et de l'APIcreateContext
de React, c'est pourquoi nous l'avons importé. - Nous avons importé
IState
etIAction
depuis./types/interfaces
. - Nous avons déclaré un objet
initialState
avec un type deIState
, et les propriétés des épisodes et des favoris, qui sont tous deux définis sur un tableau vide, respectivement. - Ensuite, nous avons créé une variable
Store
qui contient la méthodecreateContext
et qui est passéeinitialState
.
Le type de méthode createContext
est <IState | any>
<IState | any>
, ce qui signifie qu'il peut s'agir d'un type de <IState>
ou any
. Nous verrons le any
type souvent utilisé dans cet article.
- Ensuite, nous avons déclaré une fonction de
reducer
et passéstate
et l'action
en tant que paramètres. La fonctionreducer
a une instruction switch qui vérifie la valeur deaction.type
. Si la valeur estFETCH_DATA
, alors elle renvoie un objet qui a une copie de notre état(...state)
et de l'état de l'épisode qui contient notre charge utile d'action. - Dans l'instruction switch, nous renvoyons un état de
default
.
Notez que les paramètres d' state
et action
dans la fonction de réduction ont respectivement les types IState
et IAction
. En outre, la fonction de reducer
a un type de IState
.
- Enfin, nous avons déclaré une fonction
StoreProvider
. Cela donnera à tous les composants de notre application un accès au magasin. - Cette fonction prend les
children
comme prop, et à l'intérieur de la fonctionStorePrivder
, nous avons déclaré le crochetuseReducer
. - Nous avons déstructuré
state
et l'dispatch
. - Afin de rendre notre magasin accessible à tous les composants, nous avons passé une valeur d'objet contenant
state
etdispatch
.
L' state
qui contient nos épisodes et l'état de nos favoris sera rendu accessible par d'autres composants, tandis que l' dispatch
est une fonction qui change l'état.
- Nous allons exporter
Store
etStoreProvider
, afin qu'ils puissent être utilisés dans notre application.
Créer Action.ts
Nous devrons faire des requêtes à l'API pour récupérer les épisodes qui seront montrés à l'utilisateur. Cela se fera dans un fichier d'action. Créez un fichier Action.ts
, puis collez le code suivant :
import { Dispatch } from './interface/interfaces' export const fetchDataAction = async (dispatch: Dispatch) => { const URL = 'https://api.tvmaze.com/singlesearch/shows?q=la-casa-de-papel&embed=episodes' const data = await fetch(URL) const dataJSON = await data.json() return dispatch({ type: 'FETCH_DATA', payload: dataJSON.\_embedded.episodes }) }
Tout d'abord, nous devons importer nos interfaces afin qu'elles puissent être utilisées dans ce fichier. Les étapes suivantes ont été suivies pour créer l'action :
- La fonction
fetchDataAction
prend les propsdispatch
comme paramètre. - Parce que notre fonction est asynchrone, nous utiliserions
async
etawait
. - Nous créons une variable (
URL
) qui contient notre point de terminaison API. - Nous avons une autre variable nommée
data
qui contient la réponse de l'API. - Ensuite, nous stockons la réponse JSON dans
dataJSON
, après avoir obtenu la réponse au format JSON en appelantdata.json()
. - Enfin, nous renvoyons une fonction de répartition qui a une propriété de
type
et une chaîne deFETCH_DATA
. Il a également unpayload()
._embedded.episodes
est le tableau de l'objet episodes de notreendpoint
.
Notez que la fonction fetchDataAction
récupère notre point de terminaison, le convertit en objets JSON
et renvoie la fonction dispatch, qui met à jour l'état déclaré précédemment dans le Store.
Le type de dispatch exporté est défini sur React.Dispatch
. Notez que React.Dispatch
est le type standard de la fonction dispatch selon la base de code @types/react
react, tandis que <IAction>
est un tableau de l'action d'interface.
Composant EpisodesList
Afin de maintenir la réutilisabilité de notre application, nous conserverons tous les épisodes récupérés dans un fichier séparé, puis importerons le fichier dans notre composant homePage
.
Dans le dossier des components
, créez un fichier EpisodesList.tsx
, puis copiez-collez-y le code suivant :
import React from 'react' import { IEpisode, IProps } from '../types/interfaces' const EpisodesList = (props: IProps): Array<JSX.Element> => { const { episodes } = props return episodes.map((episode: IEpisode) => { return ( <section key={episode.id} className='episode-box'> <img src={!!episode.image ? episode.image.medium : ''} alt={`Money Heist ${episode.name}`} /> <div>{episode.name}</div> <section style={{ display: 'flex', justifyContent: 'space-between' }}> <div> Season: {episode.season} Number: {episode.number} </div> <button type='button' > Fav </button> </section> </section> ) }) } export default EpisodesList
- Nous importons
IEpisode
etIProps
depuisinterfaces.tsx
. - Ensuite, nous créons une fonction
EpisodesList
qui prend des accessoires. Les props auront un type deIProps
, tandis que la fonction a un type deArray<JSX.Element>
.
Visual Studio Code suggère que notre type de fonction soit écrit sous JSX.Element[]
.

Alors que Array<JSX.Element>
est égal à JSX.Element[]
, Array<JSX.Element>
est appelé l'identité générique. Par conséquent, le modèle générique sera souvent utilisé dans cet article.
- À l'intérieur de la fonction, nous déstructurons les
episodes
deprops
, qui a leIEpisode
comme type.
Lisez à propos de l'identité générique. Cette connaissance sera nécessaire au fur et à mesure que nous avancerons.
- Nous avons renvoyé les accessoires des
episodes
et les avons cartographiés pour renvoyer quelques balises HTML. - La première section contient la
key
, qui estepisode.id
, et unclassName
deepisode-box
, qui sera créé plus tard. Nous savons que nos épisodes ont des images ; d'où la balise d'image. - L'image a un opérateur ternaire qui vérifie s'il y a un
episode.image
ou unepisode.image.medium
. Sinon, nous affichons une chaîne vide si aucune image n'est trouvée. De plus, nous avons inclus l'episode.name
dans une div.
Dans la section
, nous montrons la saison à laquelle appartient un épisode et son numéro. Nous avons un bouton avec le texte Fav
. Nous avons exporté le composant EpisodesList
afin de pouvoir l'utiliser dans notre application.
Composant de la page d'accueil
Nous voulons que la page d'accueil déclenche l'appel API et affiche les épisodes à l'aide du composant EpisodesList
que nous avons créé. Dans le dossier des components
, créez le composant HomePage
, puis copiez et collez-y le code suivant :
import React, { useContext, useEffect, lazy, Suspense } from 'react' import App from '../App' import { Store } from '../Store' import { IEpisodeProps } from '../types/interfaces' import { fetchDataAction } from '../Actions' const EpisodesList = lazy<any>(() => import('./EpisodesList')) const HomePage = (): JSX.Element => { const { state, dispatch } = useContext(Store) useEffect(() => { state.episodes.length === 0 && fetchDataAction(dispatch) }) const props: IEpisodeProps = { episodes: state.episodes, store: { state, dispatch } } return ( <App> <Suspense fallback={<div>loading...</div>}> <section className='episode-layout'> <EpisodesList {...props} /> </section> </Suspense> </App> ) } export default HomePage
- Nous importons
useContext
,useEffect
,lazy
etSuspense
de React. Le composant d'application importé est le socle sur lequel tous les autres composants doivent recevoir la valeur du magasin. - Nous importons également
Store
,IEpisodeProps
etFetchDataAction
à partir de leurs fichiers respectifs. - Nous importons le composant
EpisodesList
à l'aide de la fonctionnalitéReact.lazy
disponible dans React 16.6.
Le chargement paresseux de React prend en charge la convention de fractionnement de code. Ainsi, notre composant EpisodesList
est chargé dynamiquement, au lieu d'être chargé en une fois, améliorant ainsi les performances de notre application.
- Nous déstructurons l'
state
etdispatch
en tant qu'accessoires depuis leStore
. - L'esperluette (&&) dans le crochet
useEffect
vérifie si l'état de nos épisodes estempty
(ou égal à 0). Sinon, nous renvoyons la fonctionfetchDataAction
. - Enfin, nous renvoyons le composant
App
. À l'intérieur, nous utilisons le wrapperSuspense
et définissons lefallback
sur une div avec le texte deloading
. Cela sera affiché à l'utilisateur pendant que nous attendons la réponse de l'API. - Le composant
EpisodesList
montera lorsque les données seront disponibles, et les données qui contiendront lesepisodes
seront ce que nous y diffuserons.
Configurer Index.txs
Le composant Homepage
doit être un enfant du StoreProvider
. Nous devrons le faire dans le fichier d' index
. Renommez index.js
en index.tsx
et collez le code suivant :
import React from 'react' import ReactDOM from 'react-dom' import './index.css' import { StoreProvider } from './Store' import HomePage from './components/HomePage' ReactDOM.render( <StoreProvider> <HomePage /> </StoreProvider>, document.getElementById('root') )
Nous importons StoreProvider
, HomePage
et index.css
à partir de leurs fichiers respectifs. We wrap the HomePage
component in our StoreProvider
. This makes it possible for the Homepage
component to access the store, as we saw in the previous section.
Nous sommes venus de loin. Let's check what the app looks like, without any CSS.

Create Index.css
Delete the code in the index.css
file and replace it with this:
html { font-size: 14px; } body { margin: 0; padding: 0; font-size: 10px; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } .episode-layout { display: flex; flex-wrap: wrap; min-width: 100vh; } .episode-box { padding: .5rem; } .header { display: flex; justify-content: space-between; background: white; border-bottom: 1px solid black; padding: .5rem; position: sticky; top: 0; }
Our app now has a look and feel. Here's how it looks with CSS.

Now we see that our episodes can finally be fetched and displayed, because we've adopted TypeScript all the way. Great, isn't it?
Add Favorite Episodes Feature
Let's add functionality that adds favorite episodes and that links it to a separate page. Let's go back to our Store component and add a few lines of code:
Note that the highlighted code is newly added:
import React, { useReducer, createContext } from 'react' import { IState, IAction } from './types/interfaces' const initialState: IState = { episodes: [], favourites: [] } export const Store = createContext<IState | any>(initialState) const reducer = (state: IState, action: IAction): IState => { switch (action.type) { case 'FETCH_DATA': return { ...state, episodes: action.payload }
case 'ADD_FAV': return { ...state, favourites: [...state.favourites, action.payload] }
default: return state } } export const StoreProvider = ({ children }: JSX.ElementChildrenAttribute): JSX.Element => { const [state, dispatch] = useReducer(reducer, initialState) return <Store.Provider value={{ state, dispatch }}>{children}</Store.Provider> }
To implement the “Add favorite” feature to our app, the ADD_FAV
case is added. It returns an object that holds a copy of our previous state, as well as an array with a copy of the favorite state
, with the payload
.
We need an action that will be called each time a user clicks on the FAV
button. Let's add the highlighted code to index.tx
:
import {
IAction, IEpisode, Dispatch } from './types/interfaces'
export const fetchDataAction = async (dispatch: Dispatch) => { const URL = 'https://api.tvmaze.com/singlesearch/shows?q=la-casa-de-papel&embed=episodes' const data = await fetch(URL) const dataJSON = await data.json() return dispatch({ type: 'FETCH_DATA', payload: dataJSON._embedded.episodes }) }
export const toggleFavAction = (dispatch: any, episode: IEpisode | any): IAction => { let dispatchObj = { type: 'ADD_FAV', payload: episode } return dispatch(dispatchObj) }
export const toggleFavAction = (dispatch: any, episode: IEpisode | any): IAction => { let dispatchObj = { type: 'ADD_FAV', payload: episode } return dispatch(dispatchObj) }
We create a toggleFavAction
function that takes dispatch
and episodes
as parameters, and any
and IEpisode|any
as their respective types, with IAction
as our function type. We have an object whose type
is ADD_FAV
and that has episode
as its payload. Lastly, we just return and dispatch the object.
Nous ajouterons quelques extraits supplémentaires à EpisodeList.tsx
. Copiez et collez le code en surbrillance :
import React from 'react' import { IEpisode, IProps } from '../types/interfaces' const EpisodesList = (props: IProps): Array<JSX.Element> => {
const { episodes, toggleFavAction, favourites, store } = props const { state, dispatch } = store
return episodes.map((episode: IEpisode) => { return ( <section key={episode.id} className='episode-box'> <img src={!!episode.image ? episode.image.medium : ''} alt={`Money Heist - ${episode.name}`} /> <div>{episode.name}</div> <section style={{ display: 'flex', justifyContent: 'space-between' }}> <div> Seasion: {episode.season} Number: {episode.number} </div> <button type='button'
onClick={() => toggleFavAction(state, dispatch, episode)} > {favourites.find((fav: IEpisode) => fav.id === episode.id) ? 'Unfav' : 'Fav'}
</button> </section> </section> ) }) } export default EpisodesList
Nous incluons togglefavaction
, favorites
et store
comme accessoires, et nous déstructurons state
, une dispatch
du magasin. Afin de sélectionner notre épisode préféré, nous incluons la méthode toggleFavAction
dans un événement onClick
et transmettons les accessoires state
, dispatch
et episode
comme arguments à la fonction.
Enfin, nous parcourons l'état favorite
pour vérifier si fav.id
(ID favori) correspond à episode.id
. Si c'est le cas, nous basculons entre le texte Unfav
et Fav
. Cela aide l'utilisateur à savoir s'il a ajouté cet épisode à ses favoris ou non.
Nous approchons de la fin. Mais nous avons encore besoin d'une page où les épisodes favoris peuvent être liés lorsque l'utilisateur choisit parmi les épisodes sur la page d'accueil.
Si vous êtes arrivé jusqu'ici, donnez-vous une tape dans le dos.
Composant de la page de favoris
Dans le dossier des components
, créez un fichier FavPage.tsx
. Copiez et collez-y le code suivant :
import React, { lazy, Suspense } from 'react' import App from '../App' import { Store } from '../Store' import { IEpisodeProps } from '../types/interfaces' import { toggleFavAction } from '../Actions' const EpisodesList = lazy<any>(() => import('./EpisodesList')) export default function FavPage(): JSX.Element { const { state, dispatch } = React.useContext(Store) const props: IEpisodeProps = { episodes: state.favourites, store: { state, dispatch }, toggleFavAction, favourites: state.favourites } return ( <App> <Suspense fallback={<div>loading...</div>}> <div className='episode-layout'> <EpisodesList {...props} /> </div> </Suspense> </App> ) }
Pour créer la logique derrière le choix des épisodes préférés, nous avons écrit un petit code. Nous importons lazy
et Suspense
de React. Nous importons également Store
, IEpisodeProps
et toggleFavAction
à partir de leurs fichiers respectifs.
Nous importons notre composant EpisodesList
à l'aide de la fonctionnalité React.lazy
. Enfin, nous renvoyons le composant App
. À l'intérieur, nous utilisons le wrapper Suspense
et définissons un repli sur une div avec le texte de chargement.
Cela fonctionne de la même manière que le composant de la page d' Homepage
. Ce composant accédera au magasin pour obtenir les épisodes que l'utilisateur a mis en favoris. Ensuite, la liste des épisodes est transmise au composant EpisodesList
.
Ajoutons quelques extraits supplémentaires au fichier HomePage.tsx
.
Incluez le toggleFavAction
de ../Actions
. Incluez également la méthode toggleFavAction
en tant qu'accessoires.
import React, { useContext, useEffect, lazy, Suspense } from 'react' import App from '../App' import { Store } from '../Store' import { IEpisodeProps } from '../types/interfaces'
import { fetchDataAction, toggleFavAction } from '../Actions'
const EpisodesList = lazy<any>(() => import('./EpisodesList')) const HomePage = (): JSX.Element => { const { state, dispatch } = useContext(Store) useEffect(() => { state.episodes.length === 0 && fetchDataAction(dispatch) }) const props: IEpisodeProps = { episodes: state.episodes, store: { state, dispatch },
toggleFavAction, favourites: state.favourites
} return ( <App> <Suspense fallback={<div>loading...</div>}> <section className='episode-layout'> <EpisodesList {...props} /> </section> </Suspense> </App> ) } export default HomePage
Notre FavPage
doit être liée, nous avons donc besoin d'un lien dans notre en-tête dans App.tsx
. Pour ce faire, nous utilisons Reach Router, une bibliothèque similaire à React Router. William Le explique les différences entre Reach Router et React Router.
Dans votre CLI, exécutez npm install @reach/router @types/reach__router
. Nous installons à la fois la bibliothèque Reach Router et les types reach-router
Reach.
Une fois l'installation réussie, importez Link
depuis @reach/router
.
import React, { useContext, Fragment } from 'react' import { Store } from './tsx'
import { Link } from '@reach/router'
const App = ({ children }: { children: JSX.Element }): JSX.Element => {
const { state } = useContext(Store)
return ( <Fragment> <header className='header'> <div> <h1>Money Heist</h1> <p>Pick your favourite episode</p> </div>
<div> <Link to='/'>Home</Link> <Link to='/faves'>Favourite(s): {state.favourites.length}</Link> </div>
</header> {children} </Fragment> ) } export default App
Nous déstructurons le store de useContext
. Enfin, notre maison aura un Link
et un chemin vers /
, tandis que notre favori a un chemin vers /faves
.
{state.favourites.length}
vérifie le nombre d'épisodes dans les états favoris et l'affiche.
Enfin, dans notre fichier index.tsx
, nous importons les composants FavPage
et HomePage
, respectivement, et les encapsulons dans le Router
.
Copiez le code en surbrillance dans le code existant :
import React from 'react' import ReactDOM from 'react-dom' import './index.css' import { StoreProvider } from './Store'
import { Router, RouteComponentProps } from '@reach/router' import HomePage from './components/HomePage' import FavPage from './components/FavPage' const RouterPage = ( props: { pageComponent: JSX.Element } & RouteComponentProps ) => props.pageComponent
ReactDOM.render( <StoreProvider>
<Router> <RouterPage pageComponent={<HomePage />} path='/' /> <RouterPage pageComponent={<FavPage />} path='/faves' /> </Router>
</StoreProvider>, document.getElementById('root') )
Voyons maintenant comment fonctionne l' ADD_FAV
implémenté.

Supprimer la fonctionnalité favorite
Enfin, nous ajouterons la fonction "Supprimer l'épisode", de sorte que lorsque le bouton est cliqué, nous basculons entre l'ajout ou la suppression d'un épisode favori. Nous afficherons le nombre d'épisodes ajoutés ou supprimés dans l'en-tête.
BOUTIQUE
Pour créer la fonctionnalité "Supprimer l'épisode favori", nous ajouterons un autre boîtier dans notre boutique. Allez donc sur Store.tsx
et ajoutez le code en surbrillance :
import React, { useReducer, createContext } from 'react' import { IState, IAction } from './types/interfaces' const initialState: IState = { episodes: [], favourites: [] } export const Store = createContext<IState | any>(initialState) const reducer = (state: IState, action: IAction): IState => { switch (action.type) { case 'FETCH_DATA': return { ...state, episodes: action.payload } case 'ADD_FAV': return { ...state, favourites: [...state.favourites, action.payload] }
case 'REMOVE_FAV': return { ...state, favourites: action.payload }
default: return state } } export const StoreProvider = ({ children }: JSX.ElementChildrenAttribute): JSX.Element => { const [state, dispatch] = useReducer(reducer, initialState) return {children} }
default: return state } } export const StoreProvider = ({ children }: JSX.ElementChildrenAttribute): JSX.Element => { const [state, dispatch] = useReducer(reducer, initialState) return {children} }
default: return state } } export const StoreProvider = ({ children }: JSX.ElementChildrenAttribute): JSX.Element => { const [state, dispatch] = useReducer(reducer, initialState) return {children} }
Nous ajoutons encore un autre cas nommé REMOVE_FAV
et renvoyons un objet contenant la copie de notre initialState
. En outre, l'état des favorites
contient la charge utile de l'action.
ACTION
Copiez le code en surbrillance suivant et collez-le dans action.ts
:
import
{ IAction, IEpisode, IState, Dispatch } from './types/interfaces'
export const fetchDataAction = async (dispatch: Dispatch) => { const URL = 'https://api.tvmaze.com/singlesearch/shows?q=la-casa-de-papel&embed=episodes' const data = await fetch(URL) const dataJSON = await data.json() return dispatch({ type: 'FETCH_DATA', payload: dataJSON.\_embedded.episodes }) } //Add IState withits type
export const toggleFavAction = (state: IState, dispatch: any, episode: IEpisode | any): IAction => { const episodeInFav = state.favourites.includes(episode)
let dispatchObj = { type: 'ADD_FAV', payload: episode }
if (episodeInFav) { const favWithoutEpisode = state.favourites.filter( (fav: IEpisode) => fav.id !== episode.id ) dispatchObj = { type: 'REMOVE_FAV', payload: favWithoutEpisode }
} return dispatch(dispatchObj) }
Nous importons l'interface IState
à partir de ./types/interfaces
, car nous devrons la transmettre comme type aux props d' state
dans la fonction toggleFavAction
.
Une variable episodeInFav
est créée pour vérifier si un épisode existe dans l'état des favorites
.
Nous filtrons à travers l'état des favoris pour vérifier si un ID de favori n'est pas égal à un ID d'épisode. Ainsi, le dispatchObj
se voit réattribuer un type de REMOVE_FAV
et une charge utile de favWithoutEpisode
.
Prévisualisons le résultat de notre application.
Conclusion
Dans cet article, nous avons vu comment configurer TypeScript dans un projet React et comment migrer un projet de vanilla React vers TypeScript.
Nous avons également créé une application avec TypeScript et React pour voir comment TypeScript est utilisé dans les projets React. J'espère que vous avez pu apprendre certaines choses.
Veuillez partager vos commentaires et expériences avec TypeScript dans la section des commentaires ci-dessous. J'aimerais voir ce que vous proposez!
Le référentiel de prise en charge de cet article est disponible sur GitHub.
Les références
- "Comment migrer une application React vers TypeScript", Joe Previte
- "Pourquoi et comment utiliser TypeScript dans votre application React ?", Mahesh Haldar