Table of Contents
- 2.1 Primitive Types
- 2.2 Type Inference
- 2.3 Types in functions
- 2.4 Object Types
- 2.5 Array Types
- 2.6 any, unknown and the Type Guards
- 2.7 Interface Types
- 2.8 Structural Typing
- 3.1 Union Types
- 3.2 null and undefined
- 3.3 Literal Types
- 3.4 Enum Types
- 3.5 Intersection Types
- 4.1 Different ways to write function types
- 4.2 Optional Parameters
- 4.3 Rest Parameters and Destructuring
- 4.4 Function Overloads
- 5.1 Compiler Options
- 5.2 The tsconfig.json file
- 5.3 Watch Mode
1. Getting started with TypeScript
1.1 What is TypeScript?
TypeScript is a programming language that constitutes a superset of JavaScript. This simply means that it adds a set of features to JavaScript. One of the main additions is static type checking, which reveals problems in the code as it is written, preventing many common errors that could affect users at runtime.
TypeScript also benefits from excellent integration with most IDEs like VS Code. Built-in type checking often helps detect potential problems without having to run special tools. As TypeScript code is written, it is transformed into regular JavaScript code so that it can run in a server environment or in a web browser.
Bottom line: The developer gets all the benefits of TypeScript, and end users don’t need to know anything about it.
Key Benefits:
- Error detection when writing code (not during runtime)
- Native integration with VS Code and most IDEs
- Compile to standard JavaScript, compatible with any environment
- Improved code readability and maintainability
1.2 Install TypeScript and VS Code
VS Code
VS Code includes TypeScript type checking without installing additional extensions. When loading a TypeScript file:
- Hovering over a type shows information about that type
- Type errors are indicated by a wavy red underline with an explanatory message
- All problems are visible in a panel accessible via View > Problems
Installing Node.js and TypeScript
It is recommended to install TypeScript globally via NPM (Node Package Manager), which requires installing Node.js first.
Node.js provides installation instructions for a variety of operating systems. For this training, Node 22 was used.
# Installer TypeScript globalement
npm install -g typescript
# Vérifier la version installée
tsc --version
# TypeScript 5.9
The tsc command is the TypeScript compiler. Version 5.9 is the latest version at the time of this training.
2. Core Types
2.1 Primitive Types
The basic primitive types in TypeScript are string, number and boolean. To define the type of a variable, add a colon after the variable name, followed by the type name.
Basic syntax
let bookTitle: string = "The Time Machine";
let publishedYear: number = 1895;
let price: number = 9.99;
let currentlyCheckedOut: boolean = false;
let isHardcover: boolean = true;
Demo file: 02/demos/01-primitive-types.ts
Type details
| Type | Description | Example values |
|---|---|---|
string | String | "The Time Machine", "H.G. Wells" |
number | Integer or decimal (float) | 1895, 9.99, 144 |
boolean | Logical value | true, false |
Important: Once a variable is assigned to a type, any value assigned to it must match that type. Assigning a
numberto astringvariable immediately causes an error.
Example error:
let bookTitle: string = "The Time Machine";
bookTitle = 42; // ❌ Erreur : Type 'number' is not assignable to type 'string'
Helpful tip: In the context of a library:
- The title of a book →
string - The number of pages →
number - The hardcover or paperback version →
boolean
2.2 Type Inference
TypeScript does not always require explicitly writing the type. If a variable is initialized with a value, TypeScript automatically infers (guesses) the type from that value.
// Avec déclaration explicite du type
let bookTitle: string = "The Time Machine";
// Avec inférence de type (TypeScript devine que c'est un string)
let bookTitle = "The Time Machine";
The two declarations above are equivalent: TypeScript interprets bookTitle as being of type string in both cases.
Recommendation: During the learning phase, it is recommended to write all types explicitly. This makes the code more readable and helps understand how the type system works. Once comfortable, we can start to remove some explicit types and let inference do its work.
2.3 Types in functions
Types can be defined in functions in two ways:
- On the parameters passed to the function
- On the return type of the function
Full example
Demo file: 02/demos/02-function-types.ts
// Paramètre : number | Retour : number
function daysSincePublished(publishedYear: number): number {
const today: Date = new Date();
const publishedDate: Date = new Date(publishedYear, 0, 1);
const diff: number = today.getTime() - publishedDate.getTime();
return Math.ceil(diff / (1000 * 60 * 60 * 24));
}
// Paramètre : boolean | Retour : string
function getBookStatus(isCheckedOut: boolean): string {
if (isCheckedOut) {
return `Checked Out`;
} else {
return `Available`;
}
}
// Type de retour void (ne retourne rien)
function printBookInfo(
bookTitle: string,
author: string,
genre: string,
publishedYear: number,
pageCount: number
): void {
console.log(`Title: ${bookTitle}`);
console.log(`Author: ${author}`);
console.log(`Genre: ${genre}`);
console.log(`Published Year: ${publishedYear}`);
console.log(`Page Count: ${pageCount}`);
}
The return type void
When a function returns no value (it performs operations like a console.log), the return type must be marked void. This clearly signals to the reader and compiler that this function does not produce a return value.
Note: Parameter types and return type are independent. A function can take a
booleanand return astring.
2.4 Object Types
In practice, linked data is grouped into a single structure — an object. TypeScript allows you to define the type of an object by describing the structure of its properties directly in the type declaration.
Demo file: 02/demos/03-object-types.ts
let book: {
title: string;
author: string;
publishedYear: number;
numberOfPages: number;
} = {
title: "The Time Machine",
author: "H.G. Wells",
publishedYear: 1895,
numberOfPages: 144
};
Object Type Rules
Object types must be exact matches:
| Case | Result |
|---|---|
| Wrong type value in a property | ❌ Error |
| Typo in a property name | ❌ Error |
| Additional property (5th when 4 expected) | ❌ Error |
| Missing property | ❌ Error |
| All properties correct and complete | ✅ Valid |
2.5 Array Types
In TypeScript, an array is defined by adding brackets [] after the type of its elements. This indicates that the value will contain one or more elements of that same type.
Demo file: 02/demos/04-array-types.ts
// Tableau de strings
let titles: string[] = ["The Time Machine", "Pride and Prejudice", "Frankenstein"];
// Tableau d'objets — syntaxe avec type d'objet inline
let books: { title: string; author: string; publishedYear: number; numberOfPages: number; }[];
const book1 = { title: "The Time Machine", author: "H.G. Wells", publishedYear: 1985, numberOfPages: 144 };
const book2 = { title: "Pride and Prejudice", author: "Jane Austen", publishedYear: 1813, numberOfPages: 304 };
const book3 = { title: "Frankenstein", author: "Mary Shelley", publishedYear: 1818, numberOfPages: 353 };
books = [book1, book2, book3];
Alternative syntaxes
// Syntaxe avec crochets (recommandée dans ce cours)
let titles: string[];
// Syntaxe générique alternative (équivalente)
let titles: Array<string>;
Key Point: TypeScript arrays usually contain values of the same type, but that type can itself be a complex type (such as an object with multiple properties of different types).
2.6 any, unknown and Type Guards
The any type
Type any means that any value will be valid for this variable or parameter. While this may seem convenient, it removes most of the value that TypeScript provides: the compiler will never again report that a value does not match the expected type, because everything is valid.
// Avec any : aucune protection du compilateur
function printFirstItem(arr: any): void {
console.log(arr[0].toUpperCase()); // Runtime error si arr[0] est un number
}
Problem: If we pass an array of numbers, we get an error at runtime — which the compiler had not detected.
The unknown type
unknown is a better alternative to any. It accepts any type, but forces a type check before using the value.
Demo file: 02/demos/05-unknown-type-guards.ts
function printFirstItem(arr: unknown): void {
if (Array.isArray(arr) && typeof arr[0] == 'string') {
console.log(arr[0].toUpperCase());
} else if (Array.isArray(arr) && typeof arr[0] == 'number') {
console.log(arr[0]);
} else {
console.log(`can't print`);
}
}
printFirstItem(["one", "two", "three"]);
Type Guards
A type guard is a type check in code that lets TypeScript know for sure what the type of a value is in a given block. Common type guards are:
| Type Guard | Use |
|---|---|
typeof value === 'string' | Check if a value is of type string, number, boolean |
Array.isArray(value) | Check if a value is an array |
'property' in object | Check if an object has a given property |
value instanceof ClassName | Check if a value is an instance of a class |
Comparison any vs unknown
| Criterion | any | unknown |
|---|---|---|
| Accepts all types | ✅ | ✅ |
| Verification required before use | ❌ | ✅ |
| Compiler protection | ❌ | ✅ |
| Recommended | ❌ | ✅ |
2.7 Interface Types
An interface is another way to define object types, more readable and reusable. We write the keyword interface, followed by the name (by convention with a capital letter), then a block containing the properties and their types.
Demo file: 02/demos/06-interface-types.ts
interface Book {
title: string;
author: string;
publishedYear: number;
numberOfPages: number;
}
// Utilisation de l'interface comme type de variable
let book: Book = {
title: "The Time Machine",
author: "H.G. Wells",
publishedYear: 1895,
numberOfPages: 144,
};
// Utilisation de l'interface comme type de paramètre de fonction
function printBookInfo(book: Book): void {
console.log(`Title: ${book.title}`);
console.log(`Author: ${book.author}`);
console.log(`Published Year: ${book.publishedYear}`);
console.log(`Page Count: ${book.numberOfPages}`);
}
// Utilisation de l'interface pour typer un tableau
let book1: Book = { title: "The Time Machine", author: "H.G. Wells", publishedYear: 1895, numberOfPages: 144 };
let book2: Book = { title: "Pride and Prejudice", author: "Jane Austen", publishedYear: 1813, numberOfPages: 304 };
let book3: Book = { title: "Frankenstein", author: "Mary Shelley", publishedYear: 1818, numberOfPages: 353 };
let books: Book[] = [book1, book2, book3];
Interface inheritance (extends)
Interfaces can extend other interfaces to inherit their properties:
interface User {
id: number;
username: string;
password: string;
}
// Role hérite de toutes les propriétés de User
interface Role extends User {
role: string;
expiration: Date;
}
let user: Role = {
id: 1,
username: "jon",
password: "123456",
role: "admin",
expiration: new Date()
};
Advantages of interfaces
- Centralize type definition in one place
- Reusability throughout the codebase (parameters, return types, arrays)
- Serviceability: modifying the interface reflects changes everywhere
- Possibility of extension via
extends
2.8 Structural Typing
TypeScript evaluates types by how they are defined (their structure), not by their name. This is called structural typing (or duck typing).
Basic principle
interface Book {
title: string;
author: string;
numberOfPages: number;
}
// Utilisation directe de l'interface
let book1: Book = { title: "The Time Machine", author: "H.G. Wells", numberOfPages: 144 };
// Utilisation d'un type qui correspond structurellement à Book — valide aussi
let book2 = { title: "The Time Machine", author: "H.G. Wells", numberOfPages: 144 };
// TypeScript l'interprète comme compatible avec Book
Additional properties
With structural typing, an object that has more properties than the interface defines is still valid, as long as it contains at least all the required properties.
// book3 a des propriétés supplémentaires — toujours valide avec structural typing
let book3 = {
title: "The Time Machine",
author: "H.G. Wells",
numberOfPages: 144,
isHardcover: true, // propriété supplémentaire
publishedYear: 1895 // propriété supplémentaire
};
let assignedBook: Book = book3; // ✅ Valide
Practical use case: Very useful for working with API responses. We define an interface with only the properties we need, and we assign the complete response to that interface to restrict the data.
Warning: object literals
There is a special case to be aware of: if we pass a literal object directly (without first storing it in a variable) with additional properties, the compiler will reject the assignment.
function printBookInfo(book: Book): void { /* ... */ }
// ❌ Erreur : objet littéral avec propriété supplémentaire passé directement
printBookInfo({ title: "T", author: "A", numberOfPages: 100, isHardcover: true });
// ✅ Valide : d'abord stocker dans une variable
const b = { title: "T", author: "A", numberOfPages: 100, isHardcover: true };
printBookInfo(b);
3. Union, Literal and Enum Types
3.1 Union Types
A union type allows you to declare that a value can be of more than one type. It is written with the pipe symbol | (vertical bar, Shift+\ on most keyboards).
Demo file: 03/demos/07-union-types.ts
Simple example
// Une variable peut être soit un string, soit un boolean
let value: string | boolean;
value = "hello"; // ✅ Valide
value = true; // ✅ Valide
value = 42; // ❌ Erreur
Union type with guard type
type UserId = string | number;
function lookupUser(userId: UserId): string {
if (typeof userId == 'string') {
return userId;
} else {
return `${userId}`; // Conversion number -> string
}
}
Interface union
interface PhysicalBook {
title: string;
author: string;
location: string;
}
interface EBook {
title: string;
author: string;
fileFormat: string;
downloadUrl: string;
}
type LibraryBook = PhysicalBook | EBook;
function whereIsTheBook(book: LibraryBook): string {
if ("location" in book) {
return `The physical book is located at ${book.location}`;
} else {
return `The digital book can be downloaded here ${book.downloadUrl}`;
}
}
Define a type with the type keyword
Instead of repeating the union type syntax each time it is used, we can name it with the type keyword:
// Définition
type UserId = string | number;
// Utilisation
function lookupUser(userId: UserId): string { /* ... */ }
3.2 null and undefined
null and undefined are two distinct types in TypeScript:
| Type | Meaning |
|---|---|
undefined | The value has not yet been set |
null | There will be no value |
They are generally not used alone, but often in unions.
Demo file: 03/demos/08-null-and-undefined.ts
Example with undefined
interface Book {
title: string;
author: string;
numberOfPages: number;
dueDate: Date | undefined; // undefined si le livre n'est pas emprunté
}
function isBookCheckedOut(book: Book): boolean {
if (book.dueDate == undefined) {
return false;
} else {
return true;
}
}
Example with null
interface User {
id: number;
firstName: string;
lastName: string;
middleName: string | null; // null si l'utilisateur n'a pas de deuxième prénom
}
function getFullName(user: User): string {
if (user.middleName == null) {
return `${user.firstName} ${user.lastName}`;
} else {
return `${user.firstName} ${user.middleName} ${user.lastName}`;
}
}
Rule: When using
nullorundefinedin a union type, you must always use a type guard to check the value before using it.
3.3 Literal Types
Literal types allow you to restrict a value to a specific set of specific strings (or numbers). Combined with unions, they allow you to define exactly allowed values.
Demo file: 03/demos/09-literal-types.ts
interface EBook {
title: string;
author: string;
fileFormat: 'PDF' | 'MOBI' | 'EPUB'; // Seulement ces trois valeurs sont valides
downloadUrl: string;
}
let book: EBook = {
title: "The Time Machine",
author: "H.G. Wells",
fileFormat: "PDF", // ✅ Valide
downloadUrl: "http://example.com"
};
// fileFormat: "WORD" // ❌ Erreur : "WORD" ne fait pas partie du type littéral
This technique is called narrowing. Instead of allowing any string, we restrict valid values to only expected values. This reduces errors due to typos and unhandled values.
3.4 Enum Types
enums are a TypeScript feature that allow you to create more organized literals. Like union literal types, they define a fixed number of supported values, but these are centralized in one place and accessible via enum members.
Demo file: 03/demos/10-enum-types.ts
enum FileType {
PDF,
MOBI,
EPUB,
}
interface EBook {
title: string;
author: string;
fileFormat: FileType; // Utilisation de l'enum comme type
downloadUrl: string;
}
let book: EBook = {
title: "The Time Machine",
author: "H.G. Wells",
fileFormat: FileType.PDF, // Accès via le membre de l'enum
downloadUrl: "http://example.com"
};
Use with switch and type never
To process all values of an enum, it is recommended to use a switch with a default using the never type:
function whichFormat(book: EBook): string {
switch (book.fileFormat) {
case FileType.PDF:
return `type is PDF`;
case FileType.MOBI:
return `type is MOBI`;
case FileType.EPUB:
return `type is EPUB`;
default:
// never garantit qu'on a bien couvert tous les cas
const _exhaustiveCheck: never = book.fileFormat;
return _exhaustiveCheck;
}
}
Why use never in the default?
Type never means that this value should never be assignable. If the switch reaches this default block, it means that a case has not been handled. The compiler will detect the error when adding a new value to the enum if the switch is not updated — thus avoiding runtime errors.
Enum vs Union Literal Type
| Criterion | Union Literal Type | Enum |
|---|---|---|
| Syntax | 'PDF' | 'MOBI' | 'EPUB' | enum FileType { PDF, MOBI, EPUB } |
| Centralization | Inline | In an enum block |
| Access | Direct value (“PDF”`) | Via member (FileType.PDF) |
| Recommended when | 2-3 simple values | 3+ curated values |
3.5 Intersection Types
Intersection types allow structures defined by multiple types to be merged into a single combined type. They use the symbol & (ampersand) instead of the | used by unions.
Demo file: 03/demos/11-intersection-types.ts
interface EBook {
title: string;
author: string;
fileFormat: string;
downloadUrl: string;
}
interface BookStatus {
checkedOut: boolean;
numberOfCheckouts: number;
}
// DownloadStats combine les 6 propriétés des deux interfaces
type DownloadStats = EBook & BookStatus;
let stats: DownloadStats = {
title: "The Time Machine",
author: "H.G. Wells",
fileFormat: "PDF",
downloadUrl: "http://example.com",
checkedOut: true,
numberOfCheckouts: 400,
};
Any value of type DownloadStats must define all properties of the two combined interfaces.
Common use case: Gradually add properties to types that come from API responses.
4. Function Patterns
4.1 Different ways to write function types
TypeScript supports several syntaxes for declaring functions, each with its own way of defining types.
Demo file: 04/demos/12-function-types.ts
1. Function declaration
function one(p1: string, p2: number): string {
return `function declaration ${p1} ${p2}`;
}
2. Function expression
// Avec type inféré
const two = function(p1: string, p2: number): string {
return `function expression ${p1} ${p2}`;
};
// Avec type explicite (function type expression)
const two: (string, number) => string = function(p1: string, p2: number): string {
return `function expression ${p1} ${p2}`;
};
3. Arrow function
const three: (string, number) => string = (p1: string, p2: number): string => {
return `arrow function ${p1} ${p2}`;
};
Return Type Symbol Summary
| Function type | Symbol for return type |
|---|---|
| Function declaration | : after parameter parentheses |
| Function expression | : after parameter parentheses |
| Arrow function | : after parameter parentheses |
| Function type expression | => (arrow) — no colon |
Common point of confusion: In a function type expression, we use
=>to define the return type. In an arrow function, the arrow=>marks the start of the function body — the return type uses:.
4.2 Optional Parameters
TypeScript allows marking properties or parameters as optional by adding a question mark ? after the name. This means that the value can be provided, but is not required.
Demo file: 04/demos/13-optionals.ts
Optional parameter in a function
function lookupBook(title: string, isbn?: number): boolean {
if (isbn == undefined) {
// On sait que isbn n'existe pas dans ce bloc
return true;
} else {
// On sait que isbn existe dans ce bloc
return true;
}
}
lookupBook("The Time Machine"); // ✅ isbn non fourni
lookupBook("The Time Machine", 12345); // ✅ isbn fourni
Optional property in an interface
interface Book {
title: string;
author: string;
numberOfPages: number;
publishedYear?: number; // Propriété optionnelle
}
let book1: Book = {
title: "title",
author: "author",
numberOfPages: 1,
// publishedYear omis — valide
};
let book2: Book = {
title: "title",
author: "author",
numberOfPages: 1,
publishedYear: 1900, // publishedYear fourni — aussi valide
};
Equivalence: The question mark
?is a shortcut for a union withundefined. SopublishedYear?: numberis equivalent topublishedYear: number | undefined.
4.3 Rest Parameters and Destructuring
Rest Parameters
rest parameters allow multiple parameters passed to a function to be grouped into a single array inside the function. We use the syntax with three dots ... before the variable name.
Demo file: 04/demos/14-rest-params-and-destructuring.ts
interface Book {
title: string;
author: string;
numberOfPages: number;
}
const book1: Book = { title: "The Time Machine", author: "H.G. Wells", numberOfPages: 144 };
const book2: Book = { title: "Pride and Prejudice", author: "Jane Austen", numberOfPages: 304 };
const book3: Book = { title: "Frankenstein", author: "Mary Shelley", numberOfPages: 353 };
// Le type d'un rest parameter est toujours un tableau
function printBookTitles(...books: Book[]) {
books.forEach(book => console.log(book.title));
}
// On passe des livres individuels, le rest operator les rassemble en tableau
printBookTitles(book1, book2, book3);
Destructuring
destructuring allows you to decompose an array or an object into individual variables.
function printBookInfo(book: Book): void {
console.log(`${book.title} ${book.author} ${book.numberOfPages} pages`);
}
// Avant destructuring : passage de l'objet complet
printBookInfo(book1);
// Après destructuring dans les paramètres :
function printBookInfo({ title, author, numberOfPages }: Book): void {
console.log(`${title} ${author} ${numberOfPages} pages`);
}
The use of rest parameters and destructuring is not mandatory, but they allow you to write more concise code. It’s helpful to recognize them in other people’s code.
4.4 Function Overloads
function overloads allow you to give a single function several type signatures. This allows the same function to behave differently depending on the types of parameters passed to it.
Demo file: 04/demos/15-function-overloads
How function overloads work
// Signature 1 : paramètre number -> retour avec id et dueDate
function checkoutBook(id: number): { id: number; dueDate: Date };
// Signature 2 : paramètre string -> retour avec title, author et dueDate
function checkoutBook(title: string): { title: string; author: string; dueDate: Date };
// Implémentation unique — gère les deux cas
function checkoutBook(param: number | string) {
if (typeof param === "number") {
return { id: param, dueDate: new Date(Date.now() + 7 * 86400000) };
} else {
return { title: param, author: "Unknown", dueDate: new Date(Date.now() + 7 * 86400000) };
}
}
// Utilisation — TypeScript connaît le type de retour exact selon le type du paramètre
checkoutBook(101); // Retourne { id, dueDate }
checkoutBook("The Time Machine"); // Retourne { title, author, dueDate }
Comparison: Function Overloads vs Union Return Type
Version without overload (with union of return types):
function checkoutBookUnionReturnType(
param: number | string
): { id: number; dueDate: Date } | { title: string; author: string; dueDate: Date } {
if (typeof param === "number") {
return { id: param, dueDate: new Date(Date.now() + 7 * 86400000) };
} else {
return { title: param, author: "Unknown", dueDate: new Date(Date.now() + 7 * 86400000) };
}
}
// Problème : chaque appel nécessite une vérification supplémentaire du type retourné
const bookById = checkoutBookUnionReturnType(101);
if ("id" in bookById) {
console.log(bookById.dueDate);
} else if ("title" in bookById) {
console.log(bookById.title);
}
| Criterion | Union ReturnType | Function Overloads |
|---|---|---|
| Checking returned type | Required on every call | Done only once in the body |
| Caller-side readability | Complex | Simple |
| Number of signatures | 1 | As many cases |
Tip: Overloads are useful when the function is called in multiple places and each call needs to directly access specific properties of the return type, without additional checks.
5. tsc — The TypeScript compiler
5.1 Compiler Options
tsc is the program that compiles TypeScript. Installed globally, it runs from any directory.
Basic command
# Compiler un fichier TypeScript
tsc monFichier.ts
This generates the equivalent JavaScript file. Important: Even if a TypeScript error is detected, the JavaScript file is still generated by default, because TypeScript is a development tool — generated JavaScript is still valid JavaScript, even if it doesn’t exactly match the developer’s intent.
Option noEmitOnError
To prevent JavaScript from being generated in the event of an error:
tsc --noEmitOnError monFichier.ts
With this option, if a TypeScript error is detected, no JavaScript file is created.
See all available options
tsc --all
Important options to know
| Options | Description |
|---|---|
--noEmitOnError | Does not generate JS if a TypeScript error is detected |
--noImplicitAny | Prohibits implicit any types (inferred by default) |
--strict | Enables a strict set of checks (includes noImplicitAny) |
--target <version> | Specifies the target ECMAScript version (ex: es2024) |
--outDir <folder> | Output directory for compiled JavaScript files |
--watch | Watch mode: automatically recompiles on each change |
--listEmittedFiles | Lists JavaScript files generated during compilation |
The implicit any type
Even if we never use any explicitly, it can appear by inference. When TypeScript cannot guess the type of a parameter, it assigns it any. The noImplicitAny option blocks this behavior:
// Sans noImplicitAny : TypeScript infère le paramètre comme any — aucune erreur
function printBook(book) {
console.log(`${book.title} by ${book.author}`);
}
// Avec noImplicitAny : ❌ Erreur — le type de book doit être déclaré explicitement
Demo file: 05/demos/16-sample-code.ts
// Ce code provoque une erreur avec noImplicitAny ou strict
function printBook(book) { // ❌ Paramètre sans type
console.log(`${book.title} by ${book.author}`);
}
const book = {
title: "Pride and Prejudice",
author: "Jane Austen",
};
printBook(book);
5.2 The tsconfig.json file
Instead of passing options to tsc on the command line, you can set them in a JSON file. The default name is tsconfig.json.
Create a tsconfig.json
# Méthode 1 : Créer manuellement
# Méthode 2 : Générer avec l'option --init
tsc --init
Example of tsconfig.json (demo file)
Demo file: 05/demos/tsconfig.json
{
"compilerOptions": {
"noImplicitAny": false, // Override strict — mettre à true pour réactiver
"target": "es2024", // Version ECMAScript cible
"strict": true, // Active toutes les vérifications strictes
"outDir": "dist", // Dossier de sortie des fichiers JS compilés
"listEmittedFiles": true // Liste les fichiers générés
},
"watchOptions": {
"excludeFiles": [] // Fichiers à exclure du mode watch
}
}
Top-level options (excluding compilerOptions)
{
"compilerOptions": { /* ... */ },
"include": ["src/**/*.ts"], // Fichiers à inclure dans la compilation
"exclude": ["node_modules"], // Fichiers à exclure de la compilation
"watchOptions": {
"excludeFiles": [],
"excludeDirectories": []
}
}
include: Precisely defines which TypeScript files should be compiled. Useful for compiling only part of the project.exclude: Excludes files or directories from compilation.listOmittedFiles: Whentrue, lists files that have been excluded — useful for debugging.
Example with include and listOmittedFiles
{
"compilerOptions": {
"listOmittedFiles": true,
"outDir": "dist"
},
"include": ["src/main.ts", "src/utils.ts"]
}
When tsc is run from a directory containing a tsconfig.json, it automatically reads this file for its options.
5.3 Watch Mode (Watch Mode)
watch mode is very useful during development. It monitors TypeScript files and automatically recompiles as soon as a change is detected.
Enable watch mode
tsc --watch
or the short version:
tsc -w
Configuration in tsconfig.json
{
"compilerOptions": { /* ... */ },
"watchOptions": {
"excludeFiles": ["dist/output.js"], // Fichiers à ne pas surveiller
"excludeDirectories": ["node_modules"] // Répertoires à ne pas surveiller
}
}
Behavior
- When an included TypeScript file is modified →
tscreruns for all non-excluded files - When an excluded TypeScript file is modified →
tscdoes not rerun
Tip: Take the time to correctly configure the tsconfig.json at the start of a project, then make small adjustments as new needs arise.
6. Summary of key concepts
| Concept | Quick description |
|---|---|
| Superset | TypeScript adds functionality to JavaScript |
| Static type checking | Type checking when writing code |
| Type inference | TypeScript guesses type from initial value |
string, number, boolean | Fundamental primitive types |
void | Return type of a function that returns nothing |
| Object type | Type defined by the structure of an object |
| Array type | Array of values of the same type — Type[] syntax |
any | Accept all, disable verification — avoid |
unknown | Accepts everything but requires verification before use |
| Type guard | Type checking in code (typeof, in, instanceof) |
interface | Named and reusable definition of an object type |
extends (interface) | Inheritance between interfaces |
| Structural typing | Compatibility based on structure, not name |
Union type (|) | The value can be of either type |
null | Intentional absence of value |
undefined | Value not yet defined |
| Literal type | Restriction to a set of exact values |
| Narrowing | Make a type more specific |
enum | Type grouping a fixed number of named values |
never | Type for cases that should never happen |
Intersection type (&) | Merging multiple types into one |
| Function type expression | Function type using => for return type |
Optional parameter (?) | Parameter or property that can be omitted |
Rest parameter (...) | Collects multiple parameters into an array |
| Destructuring | Breaks down an object or array into individual variables |
| Function overloads | Several type signatures for the same function |
tsc | The TypeScript compiler |
tsconfig.json | Compiler configuration file |
noImplicitAny | Prohibit implicit any |
strict | Enables all strict checks |
| Watch fashion | Automatic recompilation on each change |
Search Terms
typescript · foundations · react · frontend · development · type · types · function · union · interface · options · tsconfig.json · enum · literal · object · optional · overloads · parameters · return · unknown · comparison · compiler · destructuring · guards