2.Concepts
TS & VS Code
- Transpilation
- 3 méthodes:
- Via terminal intégré + commande tsc .ts [options]
- Via terminal intégré + commande tsc sans fichiers ni options (s'appuie alors sur tsconfig.json)
- Transpile tous les fichier *.ts du répertoire courant et sous répertoires
- Via tâche de build VS Code intégrée: Ctrl+Shift+B
- Via tâche de build VS code par défaut: F12
- "group": {
"kind": "build",
"isDefault": true,
}
- tsconfig.json:
- Contient les spécifications des options de transpilation
- tsc --init pour créer un fichier par défaut
- Debugging:
- Paramétrer le fichier de config du debugger "Launch.json":
- Construit à la volée par VSCode si tsc lancé avec sourcemap puis lancement du debugger
- Autrement le construire : Debugger > "Ouvrir launch.json" (roue crantée) + sauvegarder
- Ajouter "preLaunchTask": "${defaultBuildTask}" pour transpiler systématiquement avant de lancer le debug
- Mapping JS <-> TS :
- Soit option --sourcemap de transpilation (+ fichiers à transpiler)
- Ex: tsc test.ts --sourcemap
- Soit objet sourceMap du fichier tsconfig.json (sans indiquer de fichier)
- Ctrl + Shift + M : ouvre la fenêtre des problèmes
- IntelliSense
- Fournit via TypeScript service dans VS Code
- TypeScript version & location used by VS Code présent dans la status bar lors de visu fichier ts
Exemple de config
{
// Utilisez IntelliSense pour en savoir plus sur les attributs possibles.
// Pointez pour afficher la description des attributs existants.
// Pour plus d'informations, visitez : https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Lancer le programme",
"program": "${workspaceFolder}/index.ts",
"preLaunchTask": "${defaultBuildTask}",
"env": {
"HTTP_PORT": "8080"
},
"outFiles": [
"${workspaceFolder}/**/*.js"
]
}
]
}
{
// Consultez https://go.microsoft.com/fwlink/?LinkId=733558
// pour voir la documentation sur le format de tasks.json
"version": "2.0.0",
"tasks": [
{
"type": "typescript",
"tsconfig": "tsconfig.json",
"problemMatcher": [
"$tsc"
],
"group": {
"kind": "build",
"isDefault": true,
}
}
]
}
{
"compilerOptions": {
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
"sourceMap": true, /* Generates corresponding '.map' file. */
"outDir": "out", /* Redirect output structure to the directory. */
"strict": true, /* Enable all strict type-checking options. */
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
}
}
TS & Node.js
- Ne sait lancer qu'un fichier js:
- TypeScript: compile en JS donc pas de problème
- Spécifier l'entry point dans package.json
- Librairies NPM:
- Installer la lib npm: npm install --save
- Install la même lib pour TS: npm install --save-dev @types/
- Pour les lib natives node.js: npm install --save-dev @types/node
Types
- Built-in Types:
- Same types as with JavaScript: Boolean, Number, String, Array, null, undefined, Object
let <nom var>: <type> [= <value>];
- Template String:
- Permet d'utiliser des variables, la valeur est inséré au runtime:
xxx ${nomVar} yyyy
;
- Permet de définir des string en multi lignes
- Tuple:
let <nom var>: [<type 1>, <type 2>];
- var[0] est de type 1
- var[1] est de type 2
- Enum:
enum <nom> { <label> }
- Indice de début à 0, possible de surcharger :
<label> = <indice>, …
- Possible également de surcharger l'indice d'un label à n'importe quel moment
- Lire le libellé d'une valeur
<nom enum>[<indice>]
any
:
- Type polymorphique, peut prendre n'importe quel type
- Est défini au moment du runtime
void
:
- Pour type retour fonction/interface
never
:
- Type pour les fonctions qui ne retournent jamais quelque chose / qui déclanchent une exception
- Type assertion:
- Equivalent d'un cast
- Uniquement une "vue" de la mémoire différente, ne modifie pas la donnée mémoire elle-même
<type>(<var>);
- Type Inference:
- Used to provide type information
- Best common type algorithm utilisé pour déterminer le type des variables au runtime lorsque celui-ci n'est pas explicite
- Contextual typing: when the type of an expression is implied by its location
- Possible de désactiver avec le flag de compilation
--noImplicitAny
- Type Compatibility:
- Based on structural subtyping (= se base sur les membres)
x
is compatible with y
if y
has at least the same members as x
Declarations
- Variables:
let
const
:
- La variable ne peut plus changer de valeur
- Si c'est un objet:
- La valeur des propriétés peut changer
- La structure de l'objet ne peut pas changer (pas d'ajout / suppression de propriétés)
- Interfaces:
- Le compilateur vérifie que les propriétés déclarée dans une interface sont bien définies dans un object
- Optional property :
<prop name>?: <prop type>;
- Read only property:
- Assignable uniquement à la création
readonly <prop name>: <prop type>;
- Utilisation:
class <nom classe> implements <nom interface> [, <nom interface>] { … }
- Définition:
interface <nom> [extends <nom> [, <nom>]]
{
// Properties
<prop name>: <prop type>;
// Methods
<method name>(<params>): <return type>
}
- Classes:
- Visibilité:
- Chaque membre est public par défaut
- Visibilité private & protected = comme les autres languages objets
- Constructeur protected : pour empêcher une classe d'être instancié sans passer par une classe dérivée
- Read only property:
- Assignable uniquement à déclaration ou bien dans le constructeur
readonly <prop name>: <prop type>;
- Membre static:
- Est attaché au type plutôt qu'à l'instance
- N'est pas const par défaut !! Mais peut l'être
- Classe abstraite:
- Pour classe de base sans autoriser l'instanciation
- Pour également imposer une implémentation dans les classes dérivées
- Utilisation:
let obj : <nom classe> = new <nom classe>(<args>);
- Définition:
class <nom> [extends <nom> [, <nom>]]
{
// Properties
<visibility> <prop name>: <prop type>;
// Get/Setters
private _var: Number;
get var(): Number { return this._var; }
set var(val: Number) { this._var = val; }
// Methods
<visibility> constructor(<params>)
{
[super([<params>])] // si héritage
}
// Surcharge : redéfinition d'une méthode de classe de base
<visibility> <nom methode> (<params>): <return type>
{
// Appel méthode mère : pas obligatoire !
super.<nom methode>(<params>);
}
}
// Classe abstraite
abstract <nom>
{
// Méthode abstraite
abstract <nom methode>(): <type>;
// Méthode réelle
private test(): void { … }
}
- Functions:
- Every parameter is assumed to be required by the function (in JavaScript, every parameter is optional)
- Paramètre optionnel en TS :
?
- Initialized param:
<nom arg>: <type> = <value>
- Generics:
- Generic Function:
- Composant capable d'apporter des fonctionnalités communes sur différents types d'objets
- Utiliser type variable:
function <name><T>(v: T) { … }
- Appel de la fonction:
- En passant le type directement
- En laissant le compilateur deviner le type (inférence)
- Generic Type:
- En passant par une interface:
- En déclarant une interface avec type générique
- Cette interface déclare la signature des fonctions qu'elle propose
- En passant par une classe:
- En déclarant une classe avec type générique
- Les méthodes s'appuient sur le type passé en paramètre
- Extension:
- En général il faut déclarer une interface avec les propriétés attendues dans l'implem
- Ensuite utiliser un generic type qui peut etendre cette interface:
function <name><T extends interf>(…)
- Enum:
- Numeric ou string-based
- String-based : chaque clé doit être explicitement initialisée
- Numeric : peut être initialisé depuis une expression TS (ex: retour de fonction)
- Démarre à 0 par défault
- Namespaces:
- Permet de regrouper des définition sous un objet chapeau pour éviter les collisions de noms
- Le namespace doit explicitement exporter les définitions / objets qui doivent être accessibles
- Namespace multi fichiers:
- Dans les fichiers "enfants" il faut préciser quel est le fichier "père"
/// <reference path="nom_fichier.ts" />
- Compilation en fichier unique:
tsc --outFile fichier1.ts fichier2.ts etc…
- Modules:
- Les objets & déclarations sont privés sauf si explicitement exporté (export)
- Relationships between modules are specified in terms of imports and exports at the file level
- Un module doit être importé pour être utilisé:
- Résolution au runtime
- Loader par défaut:
- CommonJS pour Node.js
- RequireJS pour les navigateurs
- Tout fichier qui comporte un import ou export au début est considéré comme un module
- Les fichiers qui n'en ont pas sont ajouté au scope global
- Syntaxe:
- Export:
export <définition / déclaration>
- Import:
import { <nom définition ou déclaration exportés> [as <new name>] } from <chemin>;
Import * as <nom var> from <chemin>;
- NE PAS UTILISER DE NAMESPACE AVEC LES MODULES : car cela ajoute très peu de valeur
- Les modules sont natif à JS depuis ECMAScript 2015