Dans le paysage numérique actuel, qui évolue rapidement, JavaScript est devenu le langage de prédilection pour la création d’applications web dynamiques. Cependant, le typage dynamique de JavaScript peut parfois conduire à des erreurs subtiles, ce qui rend difficile de les détecter dès le début du processus de développement.
C’est là qu’intervient TypeScript, qui révolutionne la manière dont nous écrivons le code JavaScript.
Dans cet article, nous allons plonger dans le monde de TypeScript et explorer ses caractéristiques, ses avantages et ses meilleures pratiques. Vous apprendrez également comment TypeScript répond aux limites de JavaScript et libère la puissance du typage statique dans la construction d’applications web robustes et évolutives.
Plongeons dans l’aventure !
Qu’est-ce que TypeScript ?
TypeScript est un surensemble de JavaScript qui ajoute un typage statique optionnel et des fonctionnalités avancées à JavaScript. Il a été développé par Microsoft et a été initialement publié en octobre 2012. Depuis sa sortie en 2012, il a rapidement été adopté par la communauté des développeurs web.
Selon l’enquête Stack Overflow réalisée en 2022 auprès des développeurs, TypeScript est devenu la quatrième technologie la plus appréciée avec 73,46 %. TypeScript a été créé pour remédier à certaines des limites de JavaScript, telles que l’absence de typage fort, qui peut entraîner des erreurs subtiles difficiles à détecter au cours du développement.
Par exemple, considérez le code JavaScript suivant :
function add(a, b) {
return a + b;
}
let result = add(10, "20"); // No error, but result is "1020" instead of 30
Le code ci-dessus crée une fonction add
, qui est typée dynamiquement. Le type des arguments a
et b
n’est pas imposé. Par conséquent, le fait de passer une chaîne de caractères au lieu d’un nombre en tant qu’argument ne produit pas d’erreur, mais concatène les valeurs en tant que chaînes de caractères, ce qui entraîne un comportement inattendu.
Avec TypeScript, le typage statique optionnel est introduit, permettant aux développeurs de spécifier les types des variables, des paramètres de fonction et des valeurs de retour, ce qui permet de détecter les erreurs liées au type pendant le développement.
function add(a: number, b: number): number {
return a + b;
}
let result = add(10, "20"); // Error: Argument of type 'string' is not assignable to parameter of type 'number'
Dans le code TypeScript ci-dessus, les types des paramètres a
et b
sont explicitement définis comme des nombres. Si une chaîne de caractères est passée en argument, TypeScript lèvera une erreur au moment de la compilation, ce qui permettra de détecter rapidement les problèmes potentiels.
Caractéristiques de TypeScript
TypeScript offre plusieurs fonctionnalités puissantes pour le développement web moderne qui répondent à certaines des limitations de JavaScript. Ces fonctionnalités améliorent l’expérience du développeur et l’organisation du code. Elles comprennent
1. Typage statique
TypeScript dispose d’un système de typage solide qui permet de spécifier les types des variables et des paramètres de fonction au moment de la compilation. Cela permet de détecter rapidement les erreurs liées au type, ce qui rend le code plus fiable et moins sujet aux bogues.
En JavaScript, en revanche, les variables sont typées dynamiquement, ce qui signifie que leur type peut changer au cours de l’exécution.
Par exemple, le code JavaScript ci-dessous montre la déclaration de deux variables qui sont dynamiquement typées en tant que nombre et chaîne :
let num1 = 10; // num1 is dynamically typed as a number
let num2 = "20"; // num2 is dynamically typed as a string
let result = num1 + num2; // No error at compile-time
console.log(result); // Output: "1020"
Le code ci-dessus produira « 1020 », une concaténation d’un nombre et d’une chaîne de caractères. Ce n’est pas la sortie attendue – ce qui signifie que cela peut affecter votre code. L’inconvénient de JavaScript est qu’il n’envoie pas d’erreur. Vous pouvez y remédier avec TypeScript en spécifiant les types de chaque variable :
let num1: number = 10; // num1 is statically typed as a number
let num2: string = "20"; // num2 is statically typed as a string
let result = num1 + num2; // Error: Type 'string' is not assignable to type 'number'
Dans le code ci-dessus, une tentative de concaténation d’un nombre et d’une chaîne de caractères à l’aide de l’opérateur +
entraîne une erreur au moment de la compilation, car TypeScript applique une vérification stricte des types.
Cela permet de détecter les bogues potentiels liés aux types avant d’exécuter le code, ce qui permet d’obtenir un code plus robuste et sans erreur.
2. Typage optionnel
TypeScript offre une certaine flexibilité dans le choix d’utiliser ou non le typage statique. Cela signifie que vous pouvez choisir de spécifier des types pour les variables et les paramètres de fonction ou laisser TypeScript déduire automatiquement les types en fonction de la valeur attribuée.
Par exemple :
let num1: number = 10; // num1 is statically typed as a number
let num2 = "20"; // num2 is dynamically typed as a string
let result = num1 + num2; // Error: Operator '+' cannot be applied to types 'number' and 'string'
Dans ce code, le type de num2
est déduit comme étant string
sur la base de la valeur assignée, mais vous pouvez choisir de spécifier le type si vous le souhaitez.
Vous pouvez également fixer le type à any
, ce qui signifie qu’il accepte n’importe quel type de valeur :
let num1: number = 10;
let num2: any = "20";
let result = num1 + num2; // Error: Operator '+' cannot be applied to types 'number' and 'string'
3. Fonctionnalités ES6+
TypeScript prend en charge les fonctionnalités modernes de JavaScript, y compris celles introduites dans ECMAScript 6 (ES6) et les versions ultérieures.
Cela permet aux développeurs d’écrire un code plus propre et plus expressif en utilisant des fonctionnalités telles que les fonctions fléchées, la déstructuration, les modèles littéraux, et plus encore, avec une vérification de type supplémentaire.
Par exemple, les développeurs peuvent écrire un code plus propre et plus expressif :
const greeting = (name: string): string => {
return `Hello, ${name}!`; // Use of arrow function and template literal
};
console.log(greeting("John")); // Output: Hello, John!
Dans ce code, la fonction de flèche et le littéral de modèle sont parfaitement utilisés. Il en va de même pour toute la syntaxe JavaScript.
4. Organisation du code
En JavaScript, l’organisation du code dans des fichiers distincts et la gestion des dépendances peuvent s’avérer difficiles au fur et à mesure que la base de code s’étoffe. Cependant, TypeScript fournit un support intégré pour les modules et les espaces de noms afin de mieux organiser le code.
Les modules permettent d’encapsuler le code dans des fichiers distincts, ce qui facilite la gestion et la maintenance de bases de données volumineuses.
Voici un exemple :
// greeting.ts:
export function greet(name: string): string { // Export a function from a module
return `Hello, ${name}!`;
}
// app.ts:
import { greet } from "./greeting"; // Import from a module
console.log(greet("John")); // Output: Hello, John!
Dans l’exemple ci-dessus, nous avons deux fichiers distincts : greeting.ts et app.ts. Le fichier app.ts importe la fonction greet
du fichier greeting.ts à l’aide de l’instruction import
. Le fichier greeting.ts exporte la fonction greet
à l’aide du mot-clé export
, ce qui permet de l’importer dans d’autres fichiers.
Cela permet une meilleure organisation du code et une séparation des préoccupations, ce qui facilite la gestion et la maintenance de bases de code volumineuses.
Les espaces de noms en TypeScript permettent de regrouper les codes apparentés et d’éviter la pollution des espaces de noms globaux. Ils peuvent être utilisés pour définir un conteneur pour un ensemble de classes, d’interfaces, de fonctions ou de variables liées.
Voici un exemple :
namespace Utilities {
export function greet(name: string): string {
return `Hello, ${name}!`;
}
export function capitalize(str: string): string {
return str.toUpperCase();
}
}
console.log(Utilities.greet("John")); // Output: Hello, John!
console.log(Utilities.capitalize("hello")); // Output: HELLO
Dans ce code, nous définissons un namespace Utilities
qui contient deux fonctions, greet
et capitalize
. Nous pouvons accéder à ces fonctions en utilisant le nom de l’espace de noms suivi du nom de la fonction, ce qui permet de regrouper logiquement le code correspondant.
5. Caractéristiques de la programmation orientée objet (POO)
TypeScript prend en charge les concepts de la POO tels que les classes, les interfaces et l’héritage, ce qui permet de structurer et d’organiser le code.
Par exemple, TypeScript permet de créer des classes, des interfaces et des héritages :
class Person {
constructor(public name: string) {} // Define a class with a constructor
greet(): string { // Define a method in a class
return `Hello, my name is ${this.name}!`;
}
}
const john = new Person("John"); // Create an instance of the class
console.log(john.greet()); // Output: Hello, my name is John!
6. Système de type avancé
TypeScript fournit un système de type avancé qui prend en charge les génériques, les unions, les intersections et bien d’autres choses encore. Ces fonctionnalités améliorent les capacités de vérification statique des types de TypeScript, permettant aux développeurs d’écrire un code plus robuste et plus expressif.
Génériques : Les génériques permettent d’écrire un code réutilisable qui peut fonctionner avec différents types. Les génériques sont comme des espaces réservés pour les types qui sont déterminés au moment de l’exécution en fonction des valeurs passées à une fonction ou à une classe.
Par exemple, définissons une fonction générique identity qui prend une valeur d’argument du type T
et renvoie une valeur du même type T
:
function identity(value: T): T {
return value;
}
let num: number = identity(10); // T is inferred as number
let str: string = identity("hello"); // T is inferred as string
Dans l’exemple ci-dessus, le type T
est déduit sur la base du type de la valeur transmise à la fonction. Dans la première utilisation de la fonction identity, T
est déduit comme un nombre parce que nous passons 10
comme argument, et dans la deuxième utilisation, T
est déduit comme une chaîne de caractères parce que nous passons "hello"
comme argument.
Unions et intersections : Les unions et les intersections sont utilisées pour composer des types et créer des relations de type plus complexes.
Les unions permettent de combiner deux types ou plus en un seul type qui peut avoir n’importe lequel des types combinés. Les intersections permettent de combiner deux ou plusieurs types en un seul type qui doit satisfaire à tous les types combinés.
Par exemple, nous pouvons définir deux types Employee
et Manager
, représentant respectivement un employé et un directeur.
type Employee = { name: string, role: string };
type Manager = { name: string, department: string };
En utilisant les types Employee
et Manager
, nous pouvons définir un type d’union EmployeeOrManager
qui peut être soit un Employee
, soit un Manager
.
type EmployeeOrManager = Employee | Manager; // Union type
let person1: EmployeeOrManager = { name: "John", role: "Developer" }; // Can be either Employee or Manager
Dans le code ci-dessus, la variable person1
est de type EmployeeOrManager
, ce qui signifie qu’elle peut se voir assigner un objet qui satisfait au type Employee
ou Manager
.
Nous pouvons également définir un type d’intersection EmployeeOrManager
qui doit satisfaire les deux types Employee
et Manager
.
type EmployeeAndManager = Employee & Manager; // Intersection type
let person2: EmployeeAndManager = { name: "Jane", role: "Manager", department: "HR" }; // Must be both Employee and Manager
Dans le code ci-dessus, la variable person2
est de type EmployeeAndManager
, ce qui signifie qu’elle doit être un objet qui satisfait à la fois aux types Employee
et Manager
.
7. Compatibilité avec JavaScript
TypeScript est conçu pour être un surensemble de JavaScript, ce qui signifie que tout code JavaScript valide est également un code TypeScript valide. Cela facilite l’intégration de TypeScript dans les projets JavaScript existants sans avoir à réécrire tout le code.
TypeScript se construit au-dessus de JavaScript, en ajoutant un typage statique optionnel et des fonctionnalités supplémentaires, mais il vous permet toujours d’utiliser le code JavaScript tel quel.
Par exemple, si vous avez un fichier JavaScript existant app.js, vous pouvez le renommer en app.ts et commencer à utiliser progressivement les fonctionnalités de TypeScript sans modifier le code JavaScript existant. TypeScript sera toujours en mesure de comprendre et de compiler le code JavaScript en tant que TypeScript valide.
Voici un exemple de l’intégration transparente de TypeScript avec JavaScript :
// app.js - Existing JavaScript code
function greet(name) {
return "Hello, " + name + "!";
}
console.log(greet("John")); // Output: Hello, John!
Vous pouvez renommer le fichier JavaScript ci-dessus en app.ts et commencer à utiliser les fonctionnalités TypeScript :
// app.ts - Same JavaScript code as TypeScript
function greet(name: string): string {
return "Hello, " + name + "!";
}
console.log(greet("John")); // Output: Hello, John!
Dans l’exemple ci-dessus, nous ajoutons une annotation de type au paramètre name, en le spécifiant comme string
, ce qui est facultatif en TypeScript. Le reste du code est identique à celui de JavaScript. TypeScript est capable de comprendre le code JavaScript et de fournir une vérification de type pour l’annotation de type ajoutée, ce qui facilite l’adoption progressive de TypeScript dans un projet JavaScript existant.
Démarrer avec TypeScript
TypeScript est un compilateur officiel que vous pouvez installer dans votre projet à l’aide de npm. Si vous souhaitez commencer à utiliser TypeScript 5.0 dans votre projet, vous pouvez exécuter la commande suivante dans le répertoire de votre projet :
npm install -D typescript
Cela installera le compilateur dans le répertoire node_modules, que vous pouvez maintenant exécuter avec la commande npx tsc
.
Pour votre projet JavaScript, vous devrez d’abord initialiser un projet node en utilisant la commande suivante pour créer un fichier package.json :
npm init -y
Ensuite, vous pouvez installer la dépendance TypeScript, créer des fichiers TypeScript en utilisant l’extension .ts et écrire votre code TypeScript.
Une fois que vous avez écrit votre code TypeScript, vous devez le compiler en JavaScript à l’aide du compilateur TypeScript (tsc
). Vous pouvez exécuter la commande suivante dans le répertoire de votre projet :
npx tsc .ts
Cette commande compile le code TypeScript du fichier spécifié en JavaScript et génère un fichier .js portant le même nom.
Vous pouvez ensuite exécuter le code JavaScript compilé dans votre projet, comme vous le feriez avec un code JavaScript classique. Vous pouvez utiliser Node.js pour exécuter le code JavaScript dans un environnement Node.js ou inclure le fichier JavaScript compilé dans un fichier HTML et l’exécuter dans un navigateur.
Travailler avec des interfaces
Les interfaces en TypeScript sont utilisées pour définir les contrats ou la forme des objets. Elles vous permettent de spécifier la structure ou la forme à laquelle un objet doit se conformer.
Les interfaces définissent un ensemble de propriétés et/ou de méthodes qu’un objet doit posséder pour être considéré comme compatible avec l’interface. Les interfaces peuvent être utilisées pour fournir des annotations de type pour les objets, les paramètres de fonction et les valeurs de retour, ce qui permet d’améliorer la vérification statique des types et les suggestions de complétion de code dans les IDE.
Voici un exemple d’interface en TypeScript :
interface Person {
firstName: string;
lastName: string;
age: number;
}
Dans cet exemple, nous définissons une interface Person
qui spécifie trois propriétés : firstName
de type string
, lastName
de type string
, et age
de type number
.
Tout objet qui possède ces trois propriétés avec les types spécifiés sera considéré comme compatible avec l’interface Person
. Définissons maintenant des objets conformes à l’interface Person
:
let person1: Person = {
firstName: "John",
lastName: "Doe",
age: 30
};
let person2: Person = {
firstName: "Jane",
lastName: "Doe",
age: 25
};
Dans cet exemple, nous créons deux objets person1
et person2
conformes à l’interface Person
. Les deux objets possèdent les propriétés requises firstName
, lastName
, et age
avec les types spécifiés, ils sont donc compatibles avec l’interface Person
.
Extension des interfaces
Les interfaces peuvent également être étendues pour créer de nouvelles interfaces qui héritent des propriétés des interfaces existantes.
Par exemple :
interface Animal {
name: string;
sound: string;
}
interface Dog extends Animal {
breed: string;
}
let dog: Dog = {
name: "Buddy",
sound: "Woof",
breed: "Labrador"
};
Dans cet exemple, nous définissons une interface Animal
avec les propriétés name
et sound
, puis nous définissons une nouvelle interface « Dog » qui étend l’interface Animal
et ajoute une nouvelle propriété breed
. L’interface Dog
hérite des propriétés de l’interface Animal
, de sorte que tout objet conforme à l’interface Dog
doit également posséder les propriétés name
et sound
.
Propriétés optionnelles
Les interfaces peuvent également avoir des propriétés optionnelles, qui sont désignées par un ?
après le nom de la propriété.
Voici un exemple :
interface Car {
make: string;
model: string;
year?: number;
}
let car1: Car = {
make: "Toyota",
model: "Camry"
};
let car2: Car = {
make: "Honda",
model: "Accord",
year: 2020
};
Dans cet exemple, nous définissons une interface Car
avec les propriétés make
et model
, et une propriété optionnelle year
. La propriété year
n’est pas obligatoire, de sorte que les objets qui se conforment à l’interface Car
peuvent l’avoir ou non.
Vérification avancée des types
TypeScript fournit également des options avancées pour la vérification de type dans tsconfig.json. Ces options peuvent améliorer les capacités de vérification de type de votre projet TypeScript et détecter des erreurs potentielles au moment de la compilation, ce qui permet d’obtenir un code plus robuste et plus fiable.
1. strictNullChecks
Lorsque cette option vaut true
, TypeScript applique des contrôles de nullité stricts, ce qui signifie que les variables ne peuvent pas avoir une valeur de null
ou undefined
à moins d’être explicitement spécifiées avec le type d’union de null
ou undefined
.
Par exemple :
{
"compilerOptions": {
"strictNullChecks": true
}
}
Lorsque cette option est activée, TypeScript détecte les valeurs potentielles null
ou undefined
à la compilation, ce qui permet d’éviter les erreurs d’exécution causées par l’accès aux propriétés ou aux méthodes des variables null
ou undefined
.
// Example 1: Error - Object is possibly 'null'
let obj1: { prop: string } = null;
console.log(obj1.prop);
// Example 2: Error - Object is possibly 'undefined'
let obj2: { prop: string } = undefined;
console.log(obj2.prop);
2. strictFunctionTypes
Lorsque cette option vaut true
, TypeScript active la vérification stricte des types de fonction, y compris la bivariance des paramètres de fonction, ce qui garantit que les arguments de fonction sont strictement vérifiés pour la compatibilité des types.
Par exemple :
{
"compilerOptions": {
"strictFunctionTypes": true
}
}
Lorsque cette option est activée, TypeScript détecte les erreurs potentielles de type de paramètre de fonction à la compilation, ce qui permet d’éviter les erreurs d’exécution causées par le passage d’arguments incorrects aux fonctions.
// Example: Error - Argument of type 'number' is not assignable to parameter of type 'string'
function greet(name: string) {
console.log(`Hello, ${name}!`);
}
greet(123);
3. noImplicitThis
Lorsque cette option est définie sur true
, TypeScript interdit l’utilisation de this
avec un type any
implicite, ce qui permet de détecter les erreurs potentielles lors de l’utilisation de this
dans les méthodes de classe.
Par exemple :
{
"compilerOptions": {
"noImplicitThis": true
}
}
Avec cette option activée, TypeScript détectera les erreurs potentielles causées par l’utilisation de this
sans annotations de type appropriées ou sans liaison dans les méthodes de classe.
// Example: Error - The 'this' context of type 'void' is not assignable to method's 'this' of type 'MyClass'
class MyClass {
private prop: string;
constructor(prop: string) {
this.prop = prop;
}
printProp() {
console.log(this.prop);
}
}
let obj = new MyClass("Hello");
setTimeout(obj.printProp, 1000); // 'this' context is lost, potential error
4. target
L’option target
spécifie la version cible ECMAScript pour votre code TypeScript. Elle détermine la version de JavaScript que le compilateur TypeScript doit générer en sortie.
Par exemple :
{
"compilerOptions": {
"target": "ES2018"
}
}
Avec cette option réglée sur « ES2018 », TypeScript générera un code JavaScript conforme à la norme ECMAScript 2018.
Cela peut être utile si vous souhaitez profiter des dernières fonctionnalités et de la syntaxe JavaScript, mais que vous devez également assurer la rétrocompatibilité avec les environnements JavaScript plus anciens.
5. module
L’option module
spécifie le système de modules à utiliser dans votre code TypeScript. Les options courantes sont « CommonJS », « AMD », « ES6 »,« ES2015 », etc. Cela détermine la manière dont vos modules TypeScript sont compilés en modules JavaScript.
Cela détermine la manière dont vos modules TypeScript sont compilés en modules JavaScript. Par exemple :
{
"compilerOptions": {
"module": "ES6"
}
}
Si cette option est réglée sur « ES6 », TypeScript génère un code JavaScript qui utilise la syntaxe des modules ECMAScript 6.
Cela peut être utile si vous travaillez avec un environnement JavaScript moderne qui supporte les modules ECMAScript 6, comme dans une application frontend utilisant un bundler de modules comme webpack ou Rollup.
6. noUnusedLocals et noUnusedParameters
Ces options permettent à TypeScript de capturer les variables locales et les paramètres de fonction inutilisés, respectivement.
Lorsqu’elles sont définies à true
, TypeScript émettra des erreurs de compilation pour toutes les variables locales ou les paramètres de fonction qui sont déclarés mais non utilisés dans le code.
Par exemple :
{
"compilerOptions": {
"noUnusedLocals": true,
"noUnusedParameters": true
}
}
Il ne s’agit là que de quelques exemples supplémentaires d’options avancées de vérification de type dans le fichier tsconfig.json de TypeScript. Vous pouvez consulter la documentation officielle pour en savoir plus.
Meilleures pratiques et conseils pour l’utilisation de TypeScript
1. Annoter correctement les types de variables, de paramètres de fonctions et de valeurs de retour
L’un des principaux avantages de TypeScript est son solide système de typage, qui vous permet de spécifier explicitement les types des variables, des paramètres de fonction et des valeurs de retour.
Cela améliore la lisibilité du code, permet de détecter rapidement les erreurs potentielles liées au type et permet une complétion intelligente du code dans les IDE.
Voici un exemple :
// Properly annotating variable types
let age: number = 25;
let name: string = "John";
let isStudent: boolean = false;
let scores: number[] = [98, 76, 89];
let person: { name: string, age: number } = { name: "John", age: 25 };
// Properly annotating function parameter and return types
function greet(name: string): string {
return "Hello, " + name;
}
function add(a: number, b: number): number {
return a + b;
}
2. Utiliser efficacement les fonctions de type avancées de TypeScript
TypeScript est doté d’un riche ensemble de fonctionnalités de type avancées, telles que les génériques, les unions, les intersections, les types conditionnels et les types mappés. Ces fonctionnalités peuvent vous aider à écrire un code plus flexible et réutilisable.
Voici un exemple :
// Using generics to create a reusable function
function identity(value: T): T {
return value;
}
let num: number = identity(42); // inferred type: number
let str: string = identity("hello"); // inferred type: string
// Using union types to allow multiple types
function display(value: number | string): void {
console.log(value);
}
display(42); // valid
display("hello"); // valid
display(true); // error
3. Écrire un code maintenable et évolutif avec TypeScript
TypeScript encourage l’écriture d’un code maintenable et évolutif en proposant des fonctionnalités telles que des interfaces, des classes et des modules.
En voici un exemple :
// Using interfaces for defining contracts
interface Person {
name: string;
age: number;
}
function greet(person: Person): string {
return "Hello, " + person.name;
}
let john: Person = { name: "John", age: 25 };
console.log(greet(john)); // "Hello, John"
// Using classes for encapsulation and abstraction
class Animal {
constructor(private name: string, private species: string) {}
public makeSound(): void {
console.log("Animal is making a sound");
}
}
class Dog extends Animal {
constructor(name: string, breed: string) {
super(name, "Dog");
this.breed = breed;
}
public makeSound(): void {
console.log("Dog is barking");
}
}
let myDog: Dog = new Dog("Buddy", "Labrador");
myDog.makeSound(); // "Dog is barking"
4. Exploiter l’outillage et le support IDE de TypeScript
TypeScript dispose d’un excellent outil et d’un support IDE, avec des fonctionnalités telles que l’auto-complétion, l’inférence de type, le refactoring et la vérification des erreurs.
Tirez parti de ces fonctionnalités pour améliorer votre productivité et détecter les erreurs potentielles dès le début du processus de développement. Veillez à utiliser un IDE compatible avec TypeScript, tel que Visual Studio Code, et installez le plugin TypeScript pour une meilleure expérience d’édition de code.
Résumé
TypeScript offre un large éventail de fonctionnalités puissantes qui peuvent grandement améliorer vos projets de développement web.
Son typage statique fort, son système de type avancé et ses capacités de programmation orientée objet en font un outil précieux pour l’écriture d’un code maintenable, évolutif et robuste. L’outillage de TypeScript et la prise en charge de l’IDE offrent également une expérience de développement transparente.
Si vous souhaitez explorer TypeScript et ses capacités, vous pouvez le faire dès aujourd’hui grâce à l’hébergement d’applications de Kinsta.