Cours JavaScript et TypeScript · Module 6: Bases de TypeScript
Les types des paramètres et des valeurs de retour
Dans cette leçon11
Bienvenue de nouveau à Jurassic Park ! Après de nombreuses excursions à travers les interfaces et les types, le Dr Henry Wu nous emmène aujourd'hui au centre des opérations du parc, où nous allons examiner de plus près le typage des fonctions, c'est-à-dire la spécification des types des paramètres et des valeurs de retour. C'est un élément clé pour garantir la sécurité et la prévisibilité de notre système de gestion du parc, tout comme des protocoles de sécurité stricts sont essentiels au bon fonctionnement de Jurassic Park.
Les bases du typage des fonctions
Spécifier les types des paramètres et des valeurs de retour est un élément fondamental de TypeScript. Cela nous permet de définir clairement quelles données une fonction accepte et ce qu'elle retourne, créant ainsi un « contrat » clair pour cette fonction.
1// Basic function with typed parameters and return value
2function calculateFoodRequirements(
3 weight: number,
4 isPredator: boolean,
5 age: number
6): number {
7 // Predatory dinosaurs need more calories
8 const dietCoefficient = isPredator ? 0.05 : 0.03;
9
10 // Young dinosaurs need more calories per unit of mass
11 const ageCoefficient = age < 5 ? 1.2 : 1.0;
12
13 // Daily food amount in kilograms
14 return weight * dietCoefficient * ageCoefficient;
15}
16
17// Using the function
18const trexDailyMeal = calculateFoodRequirements(7500, true, 7);
19console.log(`Daily food amount for T-Rex: ${trexDailyMeal} kg`);
20
21const brachiosaurusDailyMeal = calculateFoodRequirements(35000, false, 22);
22console.log(`Daily food amount for Brachiosaurus: ${brachiosaurusDailyMeal} kg`);La fonction ci-dessus définit clairement qu'elle prend trois paramètres : weight (number), isPredator (boolean) et age (number), et qu'elle retourne une valeur de type number. Grâce à cela, l'IDE et le compilateur TypeScript pourront détecter d'éventuelles erreurs, comme une tentative d'appel de la fonction avec des types d'arguments incorrects.
Les paramètres optionnels et par défaut
À Jurassic Park, certaines procédures ont des paramètres optionnels ou des valeurs par défaut. Par exemple, lorsqu'on planifie l'examen d'un dinosaure, on peut préciser le niveau de priorité, mais si on ne le fait pas, une valeur standard est retenue.
1// Function with optional parameter
2function scheduleDinosaurExamination(
3 id: string,
4 type: "routine" | "specialist",
5 priority?: 1 | 2 | 3 // Optional parameter
6): string {
7 // If priority was not specified, we use a default value
8 const actualPriority = priority || 2;
9
10 // Determining the examination date based on priority
11 let deadlineInDays: number;
12 switch (actualPriority) {
13 case 1: deadlineInDays = 1; break; // Emergency - next day
14 case 2: deadlineInDays = 7; break; // Standard priority - one week
15 case 3: deadlineInDays = 30; break; // Low priority - one month
16 default: deadlineInDays = 7;
17 }
18
19 // Calculating the examination date
20 const examinationDate = new Date();
21 examinationDate.setDate(examinationDate.getDate() + deadlineInDays);
22
23 return `${type} examination for dinosaur ${id} scheduled for ${examinationDate.toLocaleDateString()} (priority: ${actualPriority})`;
24}
25
26// Calling with all parameters
27console.log(scheduleDinosaurExamination("TREX-01", "specialist", 1));
28
29// Calling without the optional parameter
30console.log(scheduleDinosaurExamination("STEG-03", "routine"));
31
32// Alternatively, you can use a parameter with a default value
33function scheduleDinosaurExamination2(
34 id: string,
35 type: "routine" | "specialist",
36 priority: 1 | 2 | 3 = 2 // Parameter with default value
37): string {
38 const examinationDate = new Date();
39 examinationDate.setDate(examinationDate.getDate() + (priority === 1 ? 1 : priority === 2 ? 7 : 30));
40
41 return `${type} examination for dinosaur ${id} scheduled for ${examinationDate.toLocaleDateString()} (priority: ${priority})`;
42}
43
44// Calling without providing the parameter with a default value
45console.log(scheduleDinosaurExamination2("TRIC-02", "routine"));Remarque la différence entre un paramètre optionnel (noté par ?) et un paramètre avec une valeur par défaut (spécifiée par = valeur). Dans les deux cas, on peut omettre ce paramètre lors de l'appel de la fonction, mais l'approche par valeur par défaut est plus élégante et plus lisible.
Les types des valeurs de retour
Dans le typage des fonctions, les types des valeurs de retour sont tout aussi importants que les types des paramètres. TypeScript nous permet de spécifier précisément ce qu'une fonction retourne exactement, ce qui aide à détecter d'éventuelles erreurs.
1// Function returning a number
2function calculateEnclosureCapacity(
3 length: number,
4 width: number,
5 dinosaurType: "small" | "medium" | "large"
6): number {
7 const area = length * width;
8
9 // How many dinosaurs of a given type can be safely placed in a given area
10 switch (dinosaurType) {
11 case "small": return Math.floor(area / 50);
12 case "medium": return Math.floor(area / 200);
13 case "large": return Math.floor(area / 1000);
14 default: return 0;
15 }
16}
17
18// Function returning string
19function generateDinosaurId(
20 species: string,
21 num: number
22): string {
23 // Creating an identifier based on the first 4 letters of the species and the number
24 const prefix = species.slice(0, 4).toUpperCase();
25 // Formatting the number as 3-digit with leading zeros
26 const formattedNumber = num.toString().padStart(3, '0');
27
28 return `${prefix}-${formattedNumber}`;
29}
30
31// Function returning boolean
32function isEnclosureSafe(
33 securityLevel: number,
34 requiredLevel: number,
35 lastReview: Date
36): boolean {
37 // Check if security level is sufficient
38 if (securityLevel < requiredLevel) {
39 return false;
40 }
41
42 // Check if the inspection was within the last 30 days
43 const today = new Date();
44 const thirtyDaysAgo = new Date(today);
45 thirtyDaysAgo.setDate(today.getDate() - 30);
46
47 return lastReview >= thirtyDaysAgo;
48}
49
50// Usage examples
51const raptorEnclosureCapacity = calculateEnclosureCapacity(100, 50, "medium");
52console.log(`Raptor enclosure can hold ${raptorEnclosureCapacity} individuals`);
53
54const newDinosaurId = generateDinosaurId("Velociraptor", 42);
55console.log(`New raptor received ID: ${newDinosaurId}`);
56
57const tRexEnclosureStatus = isEnclosureSafe(
58 5, // current level
59 5, // required level
60 new Date(2023, 4, 15) // date of last inspection (May 15, 2023)
61);
62console.log(`T-Rex enclosure safety status: ${tRexEnclosureStatus ? "SAFE" : "NEEDS ATTENTION"}`);Les fonctions qui retournent void
Certaines fonctions ne retournent aucune valeur : on les appelle principalement pour leurs effets de bord, comme modifier l'état du système, afficher des informations ou enregistrer des données. En TypeScript, on note ce cas avec le type de retour void.
1// Function returning no value (void)
2function registerFenceChanges(
3 enclosureId: string,
4 voltage: number,
5 changeDate: Date = new Date() // By default we use the current date
6): void {
7 // Saving information about the fence voltage change
8 console.log(`[${changeDate.toISOString()}] Voltage in enclosure ${enclosureId} fence changed to ${voltage}V`);
9
10 // In a real application we would save this data in the database
11 // The function returns no value
12}
13
14// Calling the void function
15registerFenceChanges("TRX-PADDOCK", 10000);Les fonctions qui retournent différents types (types union)
Dans certains cas, une fonction peut retourner différents types de valeurs selon les conditions ou les paramètres. En TypeScript, on peut exprimer cela à l'aide des types union.
1// Function returning different types of values
2function getDinosaurData(
3 id: string,
4 dataFormat: "summary" | "full" | "JSON"
5): string | object | null {
6 // Simulating a database
7 const database: Record<string, {
8 name: string;
9 species: string;
10 age: number;
11 weight: number;
12 healthStatus: string;
13 }> = {
14 "TREX-001": {
15 name: "Rexy",
16 species: "Tyrannosaurus Rex",
17 age: 7,
18 weight: 8000,
19 healthStatus: "good"
20 },
21 "VEL-001": {
22 name: "Blue",
23 species: "Velociraptor",
24 age: 4,
25 weight: 160,
26 healthStatus: "excellent"
27 }
28 };
29
30 // Check if the dinosaur exists
31 if (!database[id]) {
32 console.error(`Dinosaur with ID ${id} not found`);
33 return null;
34 }
35
36 const dino = database[id];
37
38 // Return different formats depending on the parameter
39 switch (dataFormat) {
40 case "summary":
41 return `${dino.name} (${dino.species}): ${dino.healthStatus}`;
42
43 case "full":
44 return `
45 ID: ${id}
46 Name: ${dino.name}
47 Species: ${dino.species}
48 Age: ${dino.age} years
49 Weight: ${dino.weight} kg
50 Health status: ${dino.healthStatus}
51 `;
52
53 case "JSON":
54 return { id, ...dino };
55
56 default:
57 return null;
58 }
59}
60
61// Usage examples
62const rexySummary = getDinosaurData("TREX-001", "summary");
63console.log(rexySummary);
64
65const fullBlueData = getDinosaurData("VEL-001", "full");
66console.log(fullBlueData);
67
68const jsonRexyData = getDinosaurData("TREX-001", "JSON") as object;
69console.log(JSON.stringify(jsonRexyData, null, 2));
70
71// Handling missing data
72const nonExistentDinosaur = getDinosaurData("INDOMINUS-001", "summary");
73if (nonExistentDinosaur === null) {
74 console.log("Dinosaur not found");
75}La fonction getDinosaurData retourne string, object ou null selon les paramètres et les conditions. Grâce aux types union, TypeScript sait que le résultat peut être l'un de ces trois types et vérifie en conséquence le code qui utilise cette fonction.
Les types de fonctions
TypeScript permet également de définir le type des fonctions elles-mêmes, ce qui est extrêmement utile lorsqu'on passe des fonctions en paramètre ou qu'on les assigne à des variables.
1// Defining a function type
2type AlarmFunction = (
3 threatLevel: number,
4 location: string,
5 message: string
6) => void;
7
8// Function using a function as a parameter
9function runSecurityProcedure(
10 enclosureId: string,
11 threatLevel: number,
12 alarmFunction: AlarmFunction
13): void {
14 console.log(`Activating security procedure for enclosure ${enclosureId}`);
15
16 // Closing gates
17 console.log(`- Closing gates of enclosure ${enclosureId}`);
18
19 // Activating additional security measures
20 if (threatLevel >= 4) {
21 console.log("- Activating additional electric fence");
22 console.log("- Dispatching security personnel");
23 }
24
25 // Calling the passed alarm function
26 alarmFunction(
27 threatLevel,
28 `Enclosure ${enclosureId}`,
29 `Security procedure level ${threatLevel} activated`
30 );
31}
32
33// Implementation of an alarm function
34const alertForControlCenter: AlarmFunction = (level, location, message) => {
35 console.log("=== ALERT FOR CONTROL CENTER ===");
36 console.log(`Threat level: ${level}`);
37 console.log(`Location: ${location}`);
38 console.log(`Message: ${message}`);
39 console.log("=================================");
40};
41
42// Alternative alarm function
43const alertForParkStaff: AlarmFunction = (level, location, message) => {
44 const priority = level >= 4 ? "CRITICAL" : level >= 2 ? "IMPORTANT" : "INFORMATIONAL";
45 console.log(`[${priority}] ${message} at ${location}`);
46};
47
48// Using the function with different alarm function implementations
49runSecurityProcedure("RAPTOR-01", 3, alertForControlCenter);
50runSecurityProcedure("TREX-01", 5, alertForParkStaff);Typer les fonctions avec callbacks
Les fonctions avec callbacks sont courantes en JavaScript, notamment dans les opérations asynchrones. TypeScript permet de typer précisément ce genre de fonctions.
1// Function with inline-typed callback
2function monitorAnimalciaHealth(
3 idAnimalcia: string,
4 intervalInSeconds: number,
5 callback: (data: { temperature: number; heartRate: number; stressLevel: number }) => void
6): void {
7 console.log(`Health monitoring started for animal ${idAnimalcia} every ${intervalInSeconds} seconds`);
8
9 // Simulating the first measurement
10 const initialData = {
11 temperature: 38.5,
12 heartRate: 72,
13 stressLevel: 3
14 };
15
16 // Calling the callback with the first data
17 callback(initialData);
18
19 console.log("Monitoring started");
20}
21
22// Using the function with a callback
23monitorAnimalciaHealth("TREX-001", 60, (data) => {
24 console.log("New health data received:");
25 console.log(`- Temperature: ${data.temperature}°C`);
26 console.log(`- Heart rate: ${data.heartRate} beats/min`);
27 console.log(`- Stress level: ${data.stressLevel}/10`);
28
29 // Checking health alerts
30 if (data.temperature > 39.5) {
31 console.log("ALERT: Elevated temperature!");
32 }
33
34 if (data.heartRate > 100) {
35 console.log("ALERT: Elevated heart rate!");
36 }
37
38 if (data.stressLevel > 7) {
39 console.log("ALERT: High stress level!");
40 }
41});
42
43// You can also define the callback type separately
44type HealthMonitoringCallback = (data: {
45 temperature: number;
46 heartRate: number;
47 stressLevel: number;
48 timeStamp?: Date; // optional parameter
49}) => void;
50
51// Function with a callback type
52function advancedHealthMonitoring(
53 idAnimalcia: string,
54 options: { interval: number; notifications: boolean },
55 callback: HealthMonitoringCallback
56): void {
57 console.log(`Configuring advanced monitoring for ${idAnimalcia}`);
58 console.log(`- Interval: ${options.interval} seconds`);
59 console.log(`- Notifications: ${options.notifications ? "enabled" : "disabled"}`);
60
61 // Simulating data with timestamp
62 const data = {
63 temperature: 38.2,
64 heartRate: 68,
65 stressLevel: 2,
66 timeStamp: new Date()
67 };
68
69 callback(data);
70}
71
72// Using the function with callback type
73advancedHealthMonitoring("STEG-003", { interval: 120, notifications: true }, (data) => {
74 const measurementTime = data.timeStamp ? data.timeStamp.toISOString() : "unknown";
75 console.log(`[${measurementTime}] Health data: T:${data.temperature}°C, HR:${data.heartRate}, Stress:${data.stressLevel}/10`);
76});Dans l'exemple ci-dessus, on a défini un type de fonction AlarmFunction, qui précise la signature d'une fonction prenant trois paramètres et ne retournant aucune valeur. On a ensuite utilisé ce type pour définir un paramètre dans la fonction runSecurityProcedure, ainsi que des implémentations concrètes de fonctions d'alarme.
Les fonctions generic
L'une des fonctionnalités les plus puissantes de TypeScript, ce sont les generics, qui permettent de créer des fonctions et des types fonctionnant avec différents types de données tout en conservant la sécurité des types.
1// Generic function for filtering data
2function filterData<T>(
3 data: T[],
4 predicate: (element: T) => boolean
5): T[] {
6 return data.filter(predicate);
7}
8
9// Sample dinosaur data
10interface DinoData {
11 id: string;
12 name: string;
13 species: string;
14 weight: number;
15 dangerLevel: number;
16}
17
18const dinosaurs: DinoData[] = [
19 { id: "TREX-001", name: "Rexy", species: "T-Rex", weight: 8000, dangerLevel: 5 },
20 { id: "VEL-001", name: "Blue", species: "Velociraptor", weight: 150, dangerLevel: 4 },
21 { id: "TRIC-001", name: "Tri", species: "Triceratops", weight: 9000, dangerLevel: 2 },
22 { id: "STEG-001", name: "Spike", species: "Stegosaurus", weight: 5000, dangerLevel: 2 },
23 { id: "BRACH-001", name: "Brachie", species: "Brachiosaurus", weight: 40000, dangerLevel: 1 }
24];
25
26// Using the generic function with type DinoData
27const dangerousDinosaurs = filterData<DinoData>(
28 dinosaurs,
29 dino => dino.dangerLevel >= 4
30);
31
32console.log("Dangerous dinosaurs:");
33dangerousDinosaurs.forEach(dino => {
34 console.log(`- ${dino.name} (${dino.species}): threat level ${dino.dangerLevel}`);
35});
36
37// Using the same function with a different data type
38const temperatures = [28.5, 29.2, 30.1, 27.8, 31.5, 30.8, 32.1, 29.5];
39const highTemperatures = filterData<number>(
40 temperatures,
41 temp => temp > 30
42);
43
44console.log(`Recorded ${highTemperatures.length} measurements with temperature above 30°C`);
45
46// More complex generic function for data operations
47function processAndReturnData<T, U>(
48 data: T[],
49 transform: (element: T) => U
50): U[] {
51 return data.map(transform);
52}
53
54// Using the complex generic function
55const dinosaurReports = processAndReturnData<DinoData, { name: string; threatLevel: string }>(
56 dinosaurs,
57 dino => ({
58 name: `${dino.name} (${dino.species})`,
59 threatLevel: dino.dangerLevel >= 4
60 ? "HIGH"
61 : dino.dangerLevel >= 3
62 ? "MEDIUM"
63 : "LOW"
64 })
65);
66
67console.log("Threat report:");
68dinosaurReports.forEach(report => {
69 console.log(`- ${report.name}: ${report.threatLevel}`);
70});Les fonctions generic sont extrêmement flexibles et permettent de réutiliser la même logique avec différents types de données tout en conservant la sécurité des types.
La surcharge de fonctions
TypeScript permet la surcharge de fonctions, qui autorise à définir plusieurs signatures de fonction avec des types de paramètres et de valeurs de retour différents.
1// Function overloading for different ID formats
2// Function signature definitions
3function generateIdentifier(type: "dinosaur", num: number): string;
4function generateIdentifier(type: "employee", firstName: string, lastName: string): string;
5function generateIdentifier(type: "location", sector: string, num: number): string;
6
7// Function implementation handling all cases
8function generateIdentifier(
9 type: "dinosaur" | "employee" | "location",
10 value1: number | string,
11 value2?: string
12): string {
13 switch (type) {
14 case "dinosaur":
15 return `DINO-${(value1 as number).toString().padStart(3, '0')}`;
16
17 case "employee":
18 if (typeof value1 === "string" && typeof value2 === "string") {
19 const initials = `${value1.charAt(0)}${value2.charAt(0)}`.toUpperCase();
20 return `EMP-${initials}-${Math.floor(Math.random() * 1000).toString().padStart(3, '0')}`;
21 }
22 throw new Error("Invalid parameters for type 'employee'");
23
24 case "location":
25 if (typeof value1 === "string" && typeof value2 === "number") {
26 return `LOC-${value1.toUpperCase()}-${value2.toString().padStart(2, '0')}`;
27 }
28 throw new Error("Invalid parameters for type 'location'");
29
30 default:
31 throw new Error(`Unknown identifier type: ${type}`);
32 }
33}
34
35// Usage examples for different overloads
36const dinosaurId = generateIdentifier("dinosaur", 42);
37console.log(`Dinosaur ID: ${dinosaurId}`);
38
39const employeeId = generateIdentifier("employee", "John", "Hammond");
40console.log(`Employee ID: ${employeeId}`);
41
42const locationId = generateIdentifier("location", "A", 5);
43console.log(`Location ID: ${locationId}`);La surcharge de fonctions permet de créer des interfaces d'API plus flexibles et plus lisibles, où une même fonction peut gérer différents jeux de paramètres.
Typer les fonctions asynchrones
En JavaScript moderne, on utilise souvent des fonctions asynchrones. TypeScript fonctionne très bien avec les Promises et les mots-clés async/await.
1// Async function returning Promise<string>
2async function getDinosaurDataFromAPI(id: string): Promise<string> {
3 console.log(`Fetching dinosaur data ${id} from API...`);
4
5 // Simulating network delay
6 await new Promise(resolve => setTimeout(resolve, 1000));
7
8 // Simulating data from API
9 const dinosaurs: Record<string, { name: string; species: string }> = {
10 "TREX-001": { name: "Rexy", species: "Tyrannosaurus Rex" },
11 "VEL-001": { name: "Blue", species: "Velociraptor" }
12 };
13
14 if (dinosaurs[id]) {
15 const dino = dinosaurs[id];
16 return `${dino.name} (${dino.species})`;
17 } else {
18 throw new Error(`Dinosaur with ID ${id} not found`);
19 }
20}
21
22// Async function returning Promise<boolean>
23async function checkHealthStatus(id: string): Promise<boolean> {
24 console.log(`Checking health status of dinosaur ${id}...`);
25
26 try {
27 // Simulating delay
28 await new Promise(resolve => setTimeout(resolve, 800));
29
30 // Simulating result (for simplicity always returns true)
31 return true;
32 } catch (error) {
33 console.error(`Error while checking health status: ${error}`);
34 return false;
35 }
36}
37
38// Async function using multiple async operations
39async function prepareDinosaurReport(id: string): Promise<{
40 id: string;
41 data: string;
42 healthStatus: boolean;
43 generationTime: string;
44}> {
45 console.log(`Preparing report for dinosaur ${id}...`);
46
47 // Parallel execution of two async operations
48 const [data, healthStatus] = await Promise.all([
49 getDinosaurDataFromAPI(id),
50 checkHealthStatus(id)
51 ]);
52
53 return {
54 id,
55 data,
56 healthStatus,
57 generationTime: new Date().toISOString()
58 };
59}
60
61// Using async functions
62async function asyncUsageExample() {
63 try {
64 const report = await prepareDinosaurReport("TREX-001");
65 console.log("Report ready:");
66 console.log(JSON.stringify(report, null, 2));
67
68 // Attempting to fetch a non-existent dinosaur
69 const nonExistent = await getDinosaurDataFromAPI("INDOMINUS-001")
70 .catch(error => {
71 console.error(`An error occurred: ${error.message}`);
72 return "Unknown dinosaur";
73 });
74
75 console.log(`Result for non-existent: ${nonExistent}`);
76 } catch (error) {
77 console.error(`An error occurred: ${error}`);
78 }
79}
80
81asyncUsageExample();Dans l'exemple ci-dessus, on a défini plusieurs fonctions asynchrones retournant différents types de promesses (Promise<string>, Promise<boolean> et Promise<object>). TypeScript offre une prise en charge complète des types pour ces fonctions et permet de chaîner en toute sécurité des opérations asynchrones.
Résumé
Typer les paramètres et les valeurs de retour des fonctions est l'un des éléments fondamentaux de TypeScript, qui aide à créer un code sûr, prévisible et facile à maintenir. Dans le contexte de notre Jurassic Park, un bon typage des fonctions, c'est comme des protocoles de sécurité solides : cela aide à prévenir d'éventuelles catastrophes avant qu'elles ne se produisent.
| Technique | Utilisation à Jurassic Park |
|---|---|
| Typage de base des fonctions | Fonctions calculant les besoins alimentaires des dinosaures |
| Paramètres optionnels et par défaut | Planification des examens de dinosaures avec différentes priorités |
| Fonctions void | Enregistrement des changements dans les systèmes de sécurité |
| Types union dans les valeurs de retour | Récupération des données de dinosaures dans différents formats |
| Types de fonctions | Définition des fonctions d'alarme pour les procédures de sécurité |
| Callbacks | Surveillance de la santé des dinosaures |
| Fonctions generic | Filtrage et traitement de différents types de données |
| Surcharge de fonctions | Génération de différents types d'identifiants |
| Fonctions asynchrones | Récupération de données depuis une API et génération de rapports |
Le Dr Wu résume ainsi : « À Jurassic Park, chaque procédure doit être précisément définie et exécutée pour garantir la sécurité de nos visiteurs comme de nos précieux spécimens. De la même façon en TypeScript, un typage correct des fonctions garantit que chaque opération se déroule exactement comme prévu, sans surprise. Et comme nous le savons tous, dans le monde des dinosaures, les surprises sont rarement agréables. »
Code de cette leçon : index.ts
1// Parameter types and return values in Jurassic Park
2console.log("Types dans les functions TypeScript\n");
3
4// ===========================================
5// 1. Basic parameter types
6// ===========================================
7console.log("=== BASIC PARAMETER TYPES ===");
8
9function feedDinosaur(name: string, amount: number): void {
10 console.log(`Feeding ${name} with ${amount}kg of food`);
11}
12
13feedDinosaur("Rexy", 400);
14feedDinosaur("Blue", 50);
15
16// ===========================================
17// 2. Return value types
18// ===========================================
19console.log("\n=== RETURN VALUE TYPES ===");
20
21// Retourne string
22function getDinosaurName(id: number): string {
23 return `Dinosaur-${id}`;
24}
25
26// Retourne number
27function calculateWeight(baseWeight: number, factor: number): number {
28 return baseWeight * factor;
29}
30
31// Retourne boolean
32function isDangerous(species: string): boolean {
33 const dangerousSpecies = ["Tyrannosaurus", "Velociraptor", "Spinosaurus"];
34 return dangerousSpecies.some(s => species.includes(s));
35}
36
37// Retourne void (ne retourne rien)
38function logStatus(message: string): void {
39 console.log(`[LOG] ${message}`);
40}
41
42console.log("Name:", getDinosaurName(1));
43console.log("Weight:", calculateWeight(1000, 1.5));
44console.log("Dangerous:", isDangerous("Tyrannosaurus Rex"));
45logStatus("System operational");
46
47// ===========================================
48// 3. Parameters optionnels
49// ===========================================
50console.log("\n=== PARAMETERS OPTIONNELS ===");
51
52function createDinosaur(
53 name: string,
54 species: string,
55 age?: number, // optionnel
56 weight?: number // optionnel
57): string {
58 let desc = `${name} (${species})`;
59 if (age !== undefined) desc += `, ${age} years old`;
60 if (weight !== undefined) desc += `, ${weight}kg`;
61 return desc;
62}
63
64console.log(createDinosaur("Rexy", "T-Rex"));
65console.log(createDinosaur("Blue", "Velociraptor", 3));
66console.log(createDinosaur("Delta", "Velociraptor", 3, 350));
67
68// ===========================================
69// 4. Default parameter values
70// ===========================================
71console.log("\n=== DEFAULT VALUES ===");
72
73function calculateFeedAmount(
74 weight: number,
75 dietType: "carnivore" | "herbivore" = "herbivore",
76 multiplier: number = 1.0
77): number {
78 const basePercentage = dietType === "carnivore" ? 0.05 : 0.10;
79 return weight * basePercentage * multiplier;
80}
81
82console.log("Carnivore 8000kg:", calculateFeedAmount(8000, "carnivore"));
83console.log("Herbivore 5000kg:", calculateFeedAmount(5000)); // default herbivore
84console.log("Herbivore 5000kg x2:", calculateFeedAmount(5000, "herbivore", 2));
85
86// ===========================================
87// 5. Rest parameters
88// ===========================================
89console.log("\n=== REST PARAMETERS ===");
90
91function createHerd(species: string, ...names: string[]): string[] {
92 return names.map(name => `${name} (${species})`);
93}
94
95const triceratopsHerd = createHerd(
96 "Triceratops",
97 "Tri",
98 "Trike",
99 "Sarah",
100 "Cera"
101);
102
103console.log("Herd:", triceratopsHerd);
104
105function sumWeights(...weights: number[]): number {
106 return weights.reduce((sum, w) => sum + w, 0);
107}
108
109console.log("Total weight:", sumWeights(8000, 350, 300, 5000));
110
111// ===========================================
112// 6. Types d'objects comme parameters
113// ===========================================
114console.log("\n=== TYPES D'OBJECTS ===");
115
116interface Dinosaur {
117 name: string;
118 species: string;
119 age: number;
120 weight: number;
121 diet: "carnivore" | "herbivore" | "omnivore";
122}
123
124function displayDinosaur(dino: Dinosaur): string {
125 return `${dino.name} - ${dino.species} (${dino.age}y, ${dino.weight}kg, ${dino.diet})`;
126}
127
128const trex: Dinosaur = {
129 name: "Rexy",
130 species: "Tyrannosaurus Rex",
131 age: 5,
132 weight: 8000,
133 diet: "carnivore"
134};
135
136console.log(displayDinosaur(trex));
137
138// Destructuring dans les parameters
139function getDinosaurInfo({ name, species, age }: Dinosaur): string {
140 return `${name} is a ${age}-year-old ${species}`;
141}
142
143console.log(getDinosaurInfo(trex));
144
145// ===========================================
146// 7. Union types dans les paramètres
147// ===========================================
148console.log("\n=== UNION TYPES ===");
149
150type ID = string | number;
151
152function findDinosaur(id: ID): string {
153 return typeof id === "string"
154 ? `Finding by string ID: ${id}`
155 : `Finding by numeric ID: ${id}`;
156}
157
158console.log(findDinosaur("DINO-001"));
159console.log(findDinosaur(42));
160
161// ===========================================
162// 8. Functions returning objects
163// ===========================================
164console.log("\n=== RETURNING OBJECTS ===");
165
166function createDinosaurRecord(
167 name: string,
168 species: string
169): { id: string; name: string; species: string; createdAt: Date } {
170 return {
171 id: `DINO-${Date.now()}`,
172 name,
173 species,
174 createdAt: new Date()
175 };
176}
177
178const newDino = createDinosaurRecord("Delta", "Velociraptor");
179console.log("New record:", newDino);
180
181// ===========================================
182// 9. Functions returning functions
183// ===========================================
184console.log("\n=== HIGHER-ORDER FUNCTIONS ===");
185
186function createMultiplier(factor: number): (value: number) => number {
187 return (value: number) => value * factor;
188}
189
190const double = createMultiplier(2);
191const triple = createMultiplier(3);
192
193console.log("Double 100:", double(100));
194console.log("Triple 100:", triple(100));
195
196// ===========================================
197// 10. Type inference
198// ===========================================
199console.log("\n=== TYPE INFERENCE ===");
200
201// TypeScript infère les types
202function inferredTypes(a: number, b: string) {
203 const sum = a + a; // number
204 const text = b + b; // string
205 return { sum, text }; // { sum: number; text: string }
206}
207
208const result = inferredTypes(5, "hello");
209console.log("Inferred result:", result);
210
211// ===========================================
212// 11. Never type
213// ===========================================
214console.log("\n=== NEVER TYPE ===");
215
216// Function never returns (always throws exception)
217function throwError(message: string): never {
218 throw new Error(message);
219}
220
221// Function never ends (infinite loop)
222function infiniteLoop(): never {
223 while (true) {
224 // infinite loop
225 }
226}
227
228console.log("Never type defined (but not called)");
229
230// ===========================================
231// 12. Overload signatures (preview)
232// ===========================================
233console.log("\n=== FUNCTION OVERLOADS - PREVIEW ===");
234
235// Overload definitions
236function processData(data: string): string;
237function processData(data: number): number;
238function processData(data: boolean): boolean;
239
240// Implémentation
241function processData(data: string | number | boolean): string | number | boolean {
242 if (typeof data === "string") {
243 return data.toUpperCase();
244 } else if (typeof data === "number") {
245 return data * 2;
246 } else {
247 return !data;
248 }
249}
250
251console.log("Process string:", processData("hello"));
252console.log("Process number:", processData(42));
253console.log("Process boolean:", processData(true));
254
255// ===========================================
256// 13. Résumé
257// ===========================================
258console.log("\n=== RÉSUMÉ ===");
259console.log("Typy parameters - specifying input types");
260console.log("Return value types - what function returns");
261console.log("Parameters optionnels - parameters avec ?");
262console.log("Default values - default values");
263console.log("Rest parameters - ...args");
264console.log("Destructuring - { prop } dans les parameters");
265console.log("Union types - string | number");
266console.log("Never - functions that never return");
267
268console.log("\nTypes de function maîtrisés !");Tu as repéré une erreur dans cette leçon ?
Teste tes connaissances
Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.
1. Quelle est la différence entre x?: string et x: string | undefined dans un paramètre de fonction ?
2. Que signifie le type de retour void en TypeScript ?
Tâches pratiques dans le jeu
- Éditeur de code
Implémente une fonction fabrique typée createDinosaur avec des interfaces pour différentes espèces.
- Tri horizontal
Ordonne les éléments d’une fonction TypeScript avec types de paramètres et de retour :