From bcb589d15e6e1d536a231545de8b81fbd0c86f07 Mon Sep 17 00:00:00 2001 From: Philippe Torrel Date: Tue, 20 Oct 2026 09:51:20 +0200 Subject: [PATCH] --- 05_typescript/linksammlung.md | 12 ++++ .../u12_type-guard/assets/js/bundle.js | 32 ++++++++++ .../uebungen/u12_type-guard/src/main.ts | 30 +++++++++ .../u13_narrowing/assets/js/bundle.js | 29 +++++++++ .../uebungen/u13_narrowing/src/main.ts | 29 +++++---- .../assets/js/bundle.js | 50 +++++++++++++++ .../u14_narrowing-equality/src/main.ts | 54 +++++++++++++++- .../u15_narrowing-in-operator/src/main.ts | 19 +++++- .../assets/js/bundle.js | 60 ++++++++++++++++++ .../u16_narrowing-zuweisung/src/main.ts | 59 +++++++++++++++--- .../assets/js/bundle.js | 35 +++++++++++ .../u17_narrowing-kontrollfluss/src/main.ts | 28 +++++++-- .../u18_type-predicates/assets/js/bundle.js | 58 ++++++++++++++++++ .../uebungen/u18_type-predicates/index.html | 4 +- .../uebungen/u18_type-predicates/src/main.ts | 60 +++++++++++++++--- .../u19_fn-typausdruecke/assets/js/bundle.js | 28 +++++++++ .../uebungen/u19_fn-typausdruecke/src/main.ts | 20 ++++-- .../assets/js/bundle.js | 21 +++++++ .../u20_fn-call-signatures/package.json | 2 +- .../u20_fn-call-signatures/src/main.ts | 61 +++++++++++++------ .../u21_fn-identity/assets/js/bundle.js | 10 +++ .../uebungen/u21_fn-identity/package.json | 2 +- .../uebungen/u21_fn-identity/src/main.ts | 7 +++ .../assets/js/05_kontrollflussanalyse.js | 3 + .../assets/js/06_type-predicate.js | 3 + .../src/04_in-operator.ts | 2 +- .../src/05_kontrollflussanalyse.ts | 5 +- .../src/06_type-predicate.ts | 3 + 28 files changed, 657 insertions(+), 69 deletions(-) create mode 100644 05_typescript/uebungen/u12_type-guard/assets/js/bundle.js create mode 100644 05_typescript/uebungen/u13_narrowing/assets/js/bundle.js create mode 100644 05_typescript/uebungen/u14_narrowing-equality/assets/js/bundle.js create mode 100644 05_typescript/uebungen/u16_narrowing-zuweisung/assets/js/bundle.js create mode 100644 05_typescript/uebungen/u17_narrowing-kontrollfluss/assets/js/bundle.js create mode 100644 05_typescript/uebungen/u18_type-predicates/assets/js/bundle.js create mode 100644 05_typescript/uebungen/u19_fn-typausdruecke/assets/js/bundle.js create mode 100644 05_typescript/uebungen/u20_fn-call-signatures/assets/js/bundle.js create mode 100644 05_typescript/uebungen/u21_fn-identity/assets/js/bundle.js diff --git a/05_typescript/linksammlung.md b/05_typescript/linksammlung.md index 7e1e5da..8e72a5f 100644 --- a/05_typescript/linksammlung.md +++ b/05_typescript/linksammlung.md @@ -68,6 +68,18 @@ - [SVG Flaggen](https://hampusborgos.github.io/country-flags/) - [Flagicons](https://flagicons.lipis.dev/) +## Terminals + +- [iterm - Unix](https://iterm2.com/) - RECOMMENDED +- [Ghostty - Unix](https://ghostty.org/) +- [Warp](https://www.warp.dev/) - ALL +- [Hyper.js](https://hyper.is/) - ALL +- [Ubuntu WSL](https://ubuntu.com/wsl) - WIN | UNIX +- [Windows Terminal](https://apps.microsoft.com/detail/9n0dx20hk701?icid=CNavAppsWindowsApps&hl=de-DE&gl=DE) - RECOMMENDED (WIN) +- [Git Bash](https://git-scm.com/) +- [Cmdr Terminal mit Bash](https://cmder.app/) + + ## Blog/ Techartikelseiten - [Dev.to](https://dev.to/) diff --git a/05_typescript/uebungen/u12_type-guard/assets/js/bundle.js b/05_typescript/uebungen/u12_type-guard/assets/js/bundle.js new file mode 100644 index 0000000..b149e62 --- /dev/null +++ b/05_typescript/uebungen/u12_type-guard/assets/js/bundle.js @@ -0,0 +1,32 @@ +(() => { + var __getOwnPropNames = Object.getOwnPropertyNames; + var __commonJS = (cb, mod) => function __require() { + try { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; + } catch (e) { + throw mod = 0, e; + } + }; + + // src/main.ts + var require_main = __commonJS({ + "src/main.ts"() { + var formatInput = (input) => { + if (typeof input === "number") { + return String(input * 100); + } else if (typeof input === "string") { + return input.toLowerCase(); + } else if (typeof input === "boolean") { + return input ? "Yes" : "No"; + } + }; + console.log(formatInput(0.5)); + console.log(formatInput(12)); + console.log(formatInput("Hello")); + console.log(formatInput("WORLD")); + console.log(formatInput(true)); + console.log(formatInput(false)); + } + }); + require_main(); +})(); diff --git a/05_typescript/uebungen/u12_type-guard/src/main.ts b/05_typescript/uebungen/u12_type-guard/src/main.ts index 328b727..d3d6699 100644 --- a/05_typescript/uebungen/u12_type-guard/src/main.ts +++ b/05_typescript/uebungen/u12_type-guard/src/main.ts @@ -1,3 +1,33 @@ +const formatInput = (input: number | string | boolean) => { + if (typeof input === 'number') { + return String(input * 100); + } else if (typeof input === 'string') { + return input.toLowerCase(); + } else if (typeof input === 'boolean') { + return input ? 'Yes' : 'No'; + } +}; + +const formatInput2 = (input: number | string | boolean) => { + let sReturn; + + switch (typeof input) { + case 'number': + sReturn = input * 100; + break; + case 'string': + sReturn = input.toLowerCase(); + break; + case 'boolean': + sReturn = input ? 'Yes' : 'No'; + break; + default: + // nothing + } + + return `formatierter string ${sReturn}`; +}; + console.log(formatInput(0.5)); // => "50" console.log(formatInput(12)); // => "1200" console.log(formatInput('Hello')); // => "hello" diff --git a/05_typescript/uebungen/u13_narrowing/assets/js/bundle.js b/05_typescript/uebungen/u13_narrowing/assets/js/bundle.js new file mode 100644 index 0000000..e40fd2b --- /dev/null +++ b/05_typescript/uebungen/u13_narrowing/assets/js/bundle.js @@ -0,0 +1,29 @@ +(() => { + var __getOwnPropNames = Object.getOwnPropertyNames; + var __commonJS = (cb, mod) => function __require() { + try { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; + } catch (e) { + throw mod = 0, e; + } + }; + + // src/main.ts + var require_main = __commonJS({ + "src/main.ts"() { + var displayStatus = (status) => { + if (status) { + return "Status: " + status; + } + return "No status available."; + return status ? `Status: ${status}` : "No status available."; + }; + console.log(displayStatus("Active")); + console.log(displayStatus("Pending")); + console.log(displayStatus(null)); + console.log(displayStatus(void 0)); + console.log(displayStatus("")); + } + }); + require_main(); +})(); diff --git a/05_typescript/uebungen/u13_narrowing/src/main.ts b/05_typescript/uebungen/u13_narrowing/src/main.ts index 4b961fb..c43bcf1 100644 --- a/05_typescript/uebungen/u13_narrowing/src/main.ts +++ b/05_typescript/uebungen/u13_narrowing/src/main.ts @@ -1,17 +1,22 @@ +// Übung 13: Implementierung der Truthiness Narrowing in einer Funktion +// Schreibe eine TypeScript-Funktion namens displayStatus, die einen Parameter status akzeptiert, der ein string, null oder undefined sein kann. Die Funktion sollte: + +// Verwende die Truthiness Narrowing, um zu prüfen, ob der Status truthy oder falsch ist. +const displayStatus = (status: string | null | undefined): string => { + // Wenn status truthy ist, wird die Zeichenfolge "Status: ", verkettet mit Status. + if (status) { + return 'Status: ' + status; + } + + // Wenn status fehlerhaft ist, wird die Zeichenfolge "No status available." zurückgegeben. + return 'No status available.'; + + return status ? `Status: ${status}` : 'No status available.'; +}; + +// Kopiere den Code unten und füge ihn ein, um deine Implementierung zu testen. console.log(displayStatus('Active')); // => "Status: Active" console.log(displayStatus('Pending')); // => "Status: Pending" console.log(displayStatus(null)); // => "No status available." console.log(displayStatus(undefined)); // => "No status available." console.log(displayStatus('')); // => "No status available." - -// Übung 13: Implementierung der Truthiness Narrowing in einer Funktion -// Schreibe eine TypeScript-Funktion namens displayStatus, die einen Parameter status akzeptiert, der ein string, null oder undefined sein kann. Die Funktion sollte: - -// Wenn status truthy ist, wird die Zeichenfolge "Status: ", verkettet mit Status. - -// Wenn status fehlerhaft ist, wird die Zeichenfolge "No status available." zurückgegeben. - -// Verwende die Truthiness Narrowing, um zu prüfen, ob der Status truthy oder falsch ist. - -// Kopiere den Code unten und füge ihn ein, um deine Implementierung zu testen. -// // Kopiere den Code unten und füge ihn ein, um deine Implementierung zu testen. diff --git a/05_typescript/uebungen/u14_narrowing-equality/assets/js/bundle.js b/05_typescript/uebungen/u14_narrowing-equality/assets/js/bundle.js new file mode 100644 index 0000000..2298c5e --- /dev/null +++ b/05_typescript/uebungen/u14_narrowing-equality/assets/js/bundle.js @@ -0,0 +1,50 @@ +(() => { + var __getOwnPropNames = Object.getOwnPropertyNames; + var __commonJS = (cb, mod) => function __require() { + try { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; + } catch (e) { + throw mod = 0, e; + } + }; + + // src/main.ts + var require_main = __commonJS({ + "src/main.ts"() { + var analyzeInput = (input) => { + if (input === true) { + return "Input is exactly true"; + } else if (input === false) { + return "Input is exactly false"; + } else if (input === 0) { + return "Input is zero"; + } else if (typeof input === "number") { + if (input > 0) { + return "Input is a positive number"; + } else if (input < 0) { + return "Input is a negative number"; + } else { + return "Unknown input"; + } + } else if (input === "hello") { + return "Input is the string 'hello'"; + } else if (typeof input === "string") { + return "Input is another string"; + } else { + return "Unknown input"; + } + }; + console.log(analyzeInput(true)); + console.log(analyzeInput(false)); + console.log(analyzeInput(0)); + console.log(analyzeInput(42)); + console.log(analyzeInput(-7)); + console.log(analyzeInput("hello")); + console.log(analyzeInput("world")); + console.log(analyzeInput("")); + console.log(analyzeInput(void 0)); + console.log(analyzeInput(null)); + } + }); + require_main(); +})(); diff --git a/05_typescript/uebungen/u14_narrowing-equality/src/main.ts b/05_typescript/uebungen/u14_narrowing-equality/src/main.ts index caeee4d..1a75fec 100644 --- a/05_typescript/uebungen/u14_narrowing-equality/src/main.ts +++ b/05_typescript/uebungen/u14_narrowing-equality/src/main.ts @@ -1,7 +1,55 @@ const analyzeInput = (input: string | number | boolean): string => { - // Your code here + if (input === true) { + return 'Input is exactly true'; + } else if (input === false) { + return 'Input is exactly false'; + } else if (input === 0) { + return 'Input is zero'; + } else if (typeof input === 'number') { + if (input > 0) { + return 'Input is a positive number'; + } else if (input < 0) { + return 'Input is a negative number'; + } else { + return 'Unknown input'; + } + } else if (input === 'hello') { + return "Input is the string 'hello'"; + } else if (typeof input === 'string') { + return 'Input is another string'; + } else { + return 'Unknown input'; + } }; +const analyzeInput2 = (input: string | number | boolean): string => { + // SESE + let sReturn; + + switch (typeof input) { + case 'boolean': + sReturn = `Input is exactly ${input ? 'true' : 'false'}`; + break; + case 'number': + if (input === 0) { + sReturn = 'Input is zero'; + } else { + sReturn = `Input is a ${input > 0 ? 'positive' : 'negative'} number`; + } + break; + case 'string': + if (input === 'hello') { + sReturn = "Input is the string 'hello'"; + } else { + sReturn = 'Input is another string'; + } + break; + default: + sReturn = 'Unknown input'; + } + + return sReturn; +}; console.log(analyzeInput(true)); // => "Input is exactly true" console.log(analyzeInput(false)); // => "Input is exactly false" console.log(analyzeInput(0)); // => "Input is zero" @@ -10,8 +58,8 @@ console.log(analyzeInput(-7)); // => "Input is a negative number" console.log(analyzeInput('hello')); // => "Input is the string 'hello'" console.log(analyzeInput('world')); // => "Input is another string" console.log(analyzeInput('')); // => "Input is another string" -console.log(analyzeInput(undefined)); // => "Unknown input" -console.log(analyzeInput(null)); // => "Unknown input" +// console.log(analyzeInput(undefined)); // => "Unknown input" +// console.log(analyzeInput(null)); // => "Unknown input" // Übung 14: Equality Narrowing in einer Funktion implementieren // Vervollständige die Funktion analyzeInput so, dass sie zurückgegeben wird: diff --git a/05_typescript/uebungen/u15_narrowing-in-operator/src/main.ts b/05_typescript/uebungen/u15_narrowing-in-operator/src/main.ts index 9bdb347..63abde6 100644 --- a/05_typescript/uebungen/u15_narrowing-in-operator/src/main.ts +++ b/05_typescript/uebungen/u15_narrowing-in-operator/src/main.ts @@ -1,13 +1,28 @@ type Guitar = { strum: () => void }; type Piano = { pressKeys: () => void }; -const play = (instrument: Guitar | Piano) => { - // Your code here +const play = (instrument: Guitar | Piano): void => { + // Die Eigenschaft "strum" grenzt den Typ auf Guitar ein. + if ('strum' in instrument) { + instrument.strum(); + } else { + instrument.pressKeys(); + } }; // Create guitar instance +const guitar: Guitar = { + strum: () => { + console.log('Strumming the guitar!'); + }, +}; // Create piano instance +const piano: Piano = { + pressKeys: () => { + console.log('Pressing piano keys!'); + }, +}; // Call functions play(guitar); // => "Strumming the guitar!" diff --git a/05_typescript/uebungen/u16_narrowing-zuweisung/assets/js/bundle.js b/05_typescript/uebungen/u16_narrowing-zuweisung/assets/js/bundle.js new file mode 100644 index 0000000..3e823b9 --- /dev/null +++ b/05_typescript/uebungen/u16_narrowing-zuweisung/assets/js/bundle.js @@ -0,0 +1,60 @@ +(() => { + var __getOwnPropNames = Object.getOwnPropertyNames; + var __commonJS = (cb, mod) => function __require() { + try { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; + } catch (e) { + throw mod = 0, e; + } + }; + + // src/main.ts + var require_main = __commonJS({ + "src/main.ts"() { + { + const handleValue2 = (value) => { + if (typeof value === "string") { + console.log(value.toUpperCase()); + } else if (typeof value === "number") { + console.log(value * 2); + } else if (typeof value === "boolean") { + console.log(value ? "It's true!" : "It's false!"); + } + }; + handleValue2("hello"); + handleValue2("TypeScript"); + handleValue2(21); + handleValue2(50); + handleValue2(false); + handleValue2(true); + } + { + let handleValue2 = function(value) { + let mReturn; + switch (typeof value) { + case "string": + mReturn = value.toUpperCase(); + break; + case "number": + mReturn = value * 2; + break; + case "boolean": + mReturn = `It\xB4s ${String(value)}!`; + break; + default: + mReturn = "Something went wrong..."; + } + }; + handleValue = handleValue2; + handleValue2("hello"); + handleValue2("TypeScript"); + handleValue2(21); + handleValue2(50); + handleValue2(false); + handleValue2(true); + } + var handleValue; + } + }); + require_main(); +})(); diff --git a/05_typescript/uebungen/u16_narrowing-zuweisung/src/main.ts b/05_typescript/uebungen/u16_narrowing-zuweisung/src/main.ts index 3c73e04..bc611f7 100644 --- a/05_typescript/uebungen/u16_narrowing-zuweisung/src/main.ts +++ b/05_typescript/uebungen/u16_narrowing-zuweisung/src/main.ts @@ -1,10 +1,51 @@ -// Test handleValue with different inputs -handleValue('hello'); // => "HELLO" -handleValue('TypeScript'); // => "TYPESCRIPT" -handleValue(21); // => 42 -handleValue(50); // => 100 -handleValue(false); // => "It's false!" -handleValue(true); // => "It's true!" +{ + const handleValue = (value: string | number | boolean): void => { + if (typeof value === 'string') { + console.log(value.toUpperCase()); + } else if (typeof value === 'number') { + console.log(value * 2); + } else if (typeof value === 'boolean') { + console.log(value ? "It's true!" : "It's false!"); + } + }; + + handleValue('hello'); // => "HELLO" + handleValue('TypeScript'); // => "TYPESCRIPT" + handleValue(21); // => 42 + handleValue(50); // => 100 + handleValue(false); // => "It's false!" + handleValue(true); // => "It's true!" +} + +{ + function handleValue(value: string | number | boolean) { + let mReturn; + + switch (typeof value) { + case 'string': + mReturn = value.toUpperCase(); + break; + case 'number': + mReturn = value * 2; + break; + case 'boolean': + mReturn = `It's ${String(value)}!`; + break; + default: + // nothing + mReturn = 'Something went wrong...'; + } + console.log(mReturn); + return mReturn; + } + + handleValue('hello'); // => "HELLO" + handleValue('TypeScript'); // => "TYPESCRIPT" + handleValue(21); // => 42 + handleValue(50); // => 100 + handleValue(false); // => "It's false!" + handleValue(true); // => "It's true!" +} // Übung 16: Type Narrowing mit Zuweisungsoperationen @@ -14,9 +55,9 @@ handleValue(true); // => "It's true!" // Anweisungen: -// 1Schreibe eine Funktion handleValue, die einen string | number | boolean Parameter annimmt und je nach Typ des Arguments ein anderes Verhalten protokolliert. +// 1. Schreibe eine Funktion handleValue, die einen string | number | boolean Parameter annimmt und je nach Typ des Arguments ein anderes Verhalten protokolliert. -// Wenn es eine string ist, protokolliere die Version in Großbuchstaben. +//- [ ] Wenn es eine string ist, protokolliere die Version in Großbuchstaben. // Wenn es sich um eine number handelt, logge ihren Wert multipliziert mit 2. diff --git a/05_typescript/uebungen/u17_narrowing-kontrollfluss/assets/js/bundle.js b/05_typescript/uebungen/u17_narrowing-kontrollfluss/assets/js/bundle.js new file mode 100644 index 0000000..efd85bc --- /dev/null +++ b/05_typescript/uebungen/u17_narrowing-kontrollfluss/assets/js/bundle.js @@ -0,0 +1,35 @@ +(() => { + var __getOwnPropNames = Object.getOwnPropertyNames; + var __commonJS = (cb, mod) => function __require() { + try { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; + } catch (e) { + throw mod = 0, e; + } + }; + + // src/main.ts + var require_main = __commonJS({ + "src/main.ts"() { + { + const handleInput = (value) => { + if (value === null) { + return "No value provided"; + } + if (typeof value === "boolean") { + return value ? "True" : "False"; + } + if (typeof value === "string") { + return value.toUpperCase(); + } + return value * value; + }; + console.log(handleInput(null)); + console.log(handleInput(true)); + console.log(handleInput("hello")); + console.log(handleInput(5)); + } + } + }); + require_main(); +})(); diff --git a/05_typescript/uebungen/u17_narrowing-kontrollfluss/src/main.ts b/05_typescript/uebungen/u17_narrowing-kontrollfluss/src/main.ts index 9daf82d..057ad96 100644 --- a/05_typescript/uebungen/u17_narrowing-kontrollfluss/src/main.ts +++ b/05_typescript/uebungen/u17_narrowing-kontrollfluss/src/main.ts @@ -1,8 +1,26 @@ -// Test cases -console.log(handleInput(null)); // => "No value provided" -console.log(handleInput(true)); // => "True" -console.log(handleInput('hello')); // => "HELLO" -console.log(handleInput(5)); // => 25 +{ + const handleInput = (value: string | number | boolean | null): string | number => { + if (value === null) { + return 'No value provided'; + } + + if (typeof value === 'boolean') { + return value ? 'True' : 'False'; + } + + if (typeof value === 'string') { + return value.toUpperCase(); + } + + return value * value; // TypeScript knows this is a number + }; + + // Test cases + console.log(handleInput(null)); // => "No value provided" + console.log(handleInput(true)); // => "True" + console.log(handleInput('hello')); // => "HELLO" + console.log(handleInput(5)); // => 25 +} // Übung 17: Kontrollflussanalyse und Type Narrowing diff --git a/05_typescript/uebungen/u18_type-predicates/assets/js/bundle.js b/05_typescript/uebungen/u18_type-predicates/assets/js/bundle.js new file mode 100644 index 0000000..29d72a1 --- /dev/null +++ b/05_typescript/uebungen/u18_type-predicates/assets/js/bundle.js @@ -0,0 +1,58 @@ +(() => { + var __getOwnPropNames = Object.getOwnPropertyNames; + var __commonJS = (cb, mod) => function __require() { + try { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; + } catch (e) { + throw mod = 0, e; + } + }; + + // src/main.ts + var require_main = __commonJS({ + "src/main.ts"() { + function isCar(vehicle) { + return typeof vehicle.drive !== "undefined"; + } + function handleVehicle(vehicle) { + if (isCar(vehicle)) { + vehicle.drive(); + } else { + vehicle.loadCargo(); + } + } + var vehicles = [ + { + drive() { + console.log("Car driving"); + } + }, + { + drive() { + console.log("Car driving"); + } + }, + { + loadCargo() { + console.log("Truck loading cargo"); + } + }, + { + loadCargo() { + console.log("Truck loading cargo"); + } + }, + { + drive() { + console.log("Car driving"); + } + } + ]; + var cars = vehicles.filter(isCar); + cars.forEach((car) => car.drive()); + handleVehicle({ drive: () => console.log("Car driving") }); + handleVehicle({ loadCargo: () => console.log("Truck loading cargo") }); + } + }); + require_main(); +})(); diff --git a/05_typescript/uebungen/u18_type-predicates/index.html b/05_typescript/uebungen/u18_type-predicates/index.html index 6da5be5..f3dd39c 100644 --- a/05_typescript/uebungen/u18_type-predicates/index.html +++ b/05_typescript/uebungen/u18_type-predicates/index.html @@ -1,4 +1,4 @@ - + @@ -29,7 +29,7 @@
  • Erstelle eine Type Predicate Funktion isCar, um zu prüfen, ob ein bestimmtes Fahrzeug ein Car ist und eine - Fahrfunktion hat. Hinweis: .drive !== undefined. + Fahrfunktion hat. Hinweis: `typeof obj.drive !== 'undefined'`.
  • Implementiere eine Funktion handleVehicle, die einen Parameter vom Typ Car | Truck akzeptiert: diff --git a/05_typescript/uebungen/u18_type-predicates/src/main.ts b/05_typescript/uebungen/u18_type-predicates/src/main.ts index 2c090f3..40bbf43 100644 --- a/05_typescript/uebungen/u18_type-predicates/src/main.ts +++ b/05_typescript/uebungen/u18_type-predicates/src/main.ts @@ -1,11 +1,3 @@ -// Test the filtered array -const cars = vehicles.filter(isCar); -cars.forEach((car) => car.drive()); // => "Car driving" - -// Test handleVehicle with both Car and Truck -handleVehicle({ drive: () => console.log('Car driving') }); // => "Car driving" -handleVehicle({ loadCargo: () => console.log('Truck loading cargo') }); // => "Truck loading cargo" - // Übung 18: Type Predicates implementieren // In dieser Aufgabe definierst du zwei verschiedene Typen und implementierst eine benutzerdefinierte Predicate Function, um zwischen ihnen zu unterscheiden. Dann benutzt du diese Funktion, um verschiedene Objekte in einem Array zu filtern und zu behandeln. @@ -14,17 +6,69 @@ handleVehicle({ loadCargo: () => console.log('Truck loading cargo') }); // => "T // 1 Definiere zwei Typen, Car und Truck, wobei: // Car hat eine Methode drive(). +type Car = { + drive(): void; + // drive: () => void; +}; // Truck hat eine Methode loadCargo(). +type Truck = { + loadCargo(): void; +}; // 2 Erstelle eine Type Predicate Funktion isCar, um zu prüfen, ob ein bestimmtes Fahrzeug ein Car ist und eine Fahrfunktion hat. Hinweis: .drive !== undefined. +function isCar(vehicle: Car | Truck): vehicle is Car { + // return Object.hasOwn(vehicle, 'drive'); + return typeof (vehicle as Car).drive !== 'undefined'; +} // 3 Implementiere eine Funktion handleVehicle, die einen Parameter vom Typ Car | Truck akzeptiert: // Wenn das Fahrzeug ein Car ist, rufe drive() an. // Wenn das Fahrzeug ein Truck ist, rufe loadCargo() an. +function handleVehicle(vehicle: Car | Truck) { + if (isCar(vehicle)) { + vehicle.drive(); + } else { + vehicle.loadCargo(); + } +} // 4 Erstelle ein Array von Car | Truck Objekten und filtere nur die Autos mit dem isCar Predicate heraus. +const vehicles = [ + { + drive() { + console.log('Car driving'); + }, + }, + { + drive() { + console.log('Car driving'); + }, + }, + { + loadCargo() { + console.log('Truck loading cargo'); + }, + }, + { + loadCargo() { + console.log('Truck loading cargo'); + }, + }, + { + drive() { + console.log('Car driving'); + }, + }, +]; // 5 Teste deine Funktionen mit verschiedenen Eingaben. +// Test the filtered array +const cars = vehicles.filter(isCar); +cars.forEach((car) => car.drive()); // => "Car driving" + +// Test handleVehicle with both Car and Truck +handleVehicle({ drive: () => console.log('Car driving') }); // => "Car driving" +handleVehicle({ loadCargo: () => console.log('Truck loading cargo') }); // => "Truck loading cargo" diff --git a/05_typescript/uebungen/u19_fn-typausdruecke/assets/js/bundle.js b/05_typescript/uebungen/u19_fn-typausdruecke/assets/js/bundle.js new file mode 100644 index 0000000..4e92dd7 --- /dev/null +++ b/05_typescript/uebungen/u19_fn-typausdruecke/assets/js/bundle.js @@ -0,0 +1,28 @@ +(() => { + var __getOwnPropNames = Object.getOwnPropertyNames; + var __commonJS = (cb, mod) => function __require() { + try { + return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; + } catch (e) { + throw mod = 0, e; + } + }; + + // src/main.ts + var require_main = __commonJS({ + "src/main.ts"() { + var calculate = (operation, a, b) => { + return operation(a, b); + }; + var add = (a, b) => { + return a + b; + }; + var multiply = (a, b) => { + return a * b; + }; + console.log(calculate(add, 10, 5)); + console.log(calculate(multiply, 10, 5)); + } + }); + require_main(); +})(); diff --git a/05_typescript/uebungen/u19_fn-typausdruecke/src/main.ts b/05_typescript/uebungen/u19_fn-typausdruecke/src/main.ts index 1f02bac..2691690 100644 --- a/05_typescript/uebungen/u19_fn-typausdruecke/src/main.ts +++ b/05_typescript/uebungen/u19_fn-typausdruecke/src/main.ts @@ -1,7 +1,3 @@ -// Test cases -console.log(calculate(add, 10, 5)); // => 15 -console.log(calculate(multiply, 10, 5)); // => 50 - // Übung 19: Arbeiten mit Function Type Expressions // In dieser Aufgabe schreibst du eine Funktion, die andere Funktionen als Parameter akzeptiert und Logik basierend auf diesen Function Type Expressions implementiert. @@ -9,9 +5,25 @@ console.log(calculate(multiply, 10, 5)); // => 50 // Anweisungen: // 1 Definiere einen Type Alias MathOperation für eine Funktion, die zwei numbers als Parameter nimmt und einen number zurückgibt. +type MathOperation = (a: number, b: number) => number; // 2 Implementiere eine Funktion calculate, die eine Funktion vom Typ MathOperation und zwei numbers annimmt und die Funktion auf die Zahlen anwendet. +const calculate = (operation: MathOperation, a: number, b: number) => { + return operation(a, b); +}; // 3 Erstelle zwei neue Funktionen, add und multiply, die der Signatur MathOperation entsprechen. +const add: MathOperation = (a, b) => { + return a + b; +}; + +const multiply: MathOperation = (a, b) => { + return a * b; +}; + // 4 Teste alle Funktionen, indem du geeignete Argumente übergibst und die Ergebnisse protokollierst. + +// Test cases +console.log(calculate(add, 10, 5)); // => 15 +console.log(calculate(multiply, 10, 5)); // => 50 diff --git a/05_typescript/uebungen/u20_fn-call-signatures/assets/js/bundle.js b/05_typescript/uebungen/u20_fn-call-signatures/assets/js/bundle.js new file mode 100644 index 0000000..f50f42f --- /dev/null +++ b/05_typescript/uebungen/u20_fn-call-signatures/assets/js/bundle.js @@ -0,0 +1,21 @@ +(() => { + // src/main.ts + var double = (value) => value * 2; + var halve = (value) => value / 2; + var describeAndApply = (operation, value) => { + console.log(operation.description); + return operation(value); + }; + var describableDouble = Object.assign(double, { + description: "This operation doubles the number." + }); + var describableHalve = Object.assign(halve, { + description: "This operation halves the number." + }); + console.log(describeAndApply(describableDouble, 10)); + console.log(describeAndApply(describableHalve, 10)); + console.log(describeAndApply(describableDouble, -3)); + console.log(describeAndApply(describableHalve, 7)); + console.log(double(0)); + console.log(halve(0)); +})(); diff --git a/05_typescript/uebungen/u20_fn-call-signatures/package.json b/05_typescript/uebungen/u20_fn-call-signatures/package.json index 61f867a..bedd2ef 100644 --- a/05_typescript/uebungen/u20_fn-call-signatures/package.json +++ b/05_typescript/uebungen/u20_fn-call-signatures/package.json @@ -9,5 +9,5 @@ "keywords": [], "author": "", "license": "ISC", - "type": "commonjs" + "type": "module" } diff --git a/05_typescript/uebungen/u20_fn-call-signatures/src/main.ts b/05_typescript/uebungen/u20_fn-call-signatures/src/main.ts index 618142b..3d05428 100644 --- a/05_typescript/uebungen/u20_fn-call-signatures/src/main.ts +++ b/05_typescript/uebungen/u20_fn-call-signatures/src/main.ts @@ -1,23 +1,3 @@ -// Step 1: Define the NumberOperation call signature - -// Step 2: Implement double and halve functions - -// Step 3: Define the DescribableNumberOperation type - -// Step 4: Implement describeAndApply function - -// Test all functions -const describableDouble: DescribableNumberOperation = Object.assign(double, { - description: 'This operation doubles the number.', -}); - -const describableHalve: DescribableNumberOperation = Object.assign(halve, { - description: 'This operation halves the number.', -}); - -console.log(describeAndApply(describableDouble, 10)); // => 20 -console.log(describeAndApply(describableHalve, 10)); // => 5 - // Übung 20: Call Signatures für Zahlenoperationen // In dieser Übung erstellst und verwendest du ein paar einfache Funktionen, die sich an bestimmte Call Signatures für die Arbeit mit Zahlen halten. @@ -26,13 +6,54 @@ console.log(describeAndApply(describableHalve, 10)); // => 5 // 1 Definiere eine Funktion vom Typ NumberOperation, die ein einzelnes number annimmt und ein number zurückgibt. +// Die Call Signature beschreibt, wie eine passende Funktion aufgerufen wird. +type NumberOperation = { + (value: number): number; +}; +type NumberFn = (value: number) => number; + // 2 Implementiere zwei Funktionen, double und halve, die der Call Signature NumberOperation folgen: // double: Multipliziert die eingegebene Zahl mit 2. // halve: Teilt die eingegebene Zahl durch 2. +// Der Parametertyp wird jeweils aus NumberOperation abgeleitet. +const double: NumberOperation = (value) => value * 2; +const halve: NumberOperation = (value) => value / 2; + +const double2: NumberFn = (value) => value * 2; +const halve2: NumberFn = (value) => value / 2; + // 3 Definiere einen Objekttyp DescribableNumberOperation mit einer description-Property vom Typ string und einer Cal Signature, die NumberOperation entspricht. +// Dieser Typ kombiniert eine Eigenschaft mit einer Call Signature. +type DescribableNumberOperation = { + description: string; + (value: number): number; +}; + // 4 Implementiere eine Funktion describeAndApply, die ein DescribableNumberOperation Objekt annimmt, dessen description protokolliert und die Operation auf eine bestimmte Zahl anwendet. +const describeAndApply = (operation: DescribableNumberOperation, value: number): number => { + console.log(operation.description); + return operation(value); +}; + // 5 Teste alle Funktionen mit ein paar Zahlen. + +// Object.assign ergänzt die Funktionen um die description-Eigenschaft. +// Die Funktionen bleiben dabei aufrufbar. +const describableDouble: DescribableNumberOperation = Object.assign(double, { + description: 'This operation doubles the number.', +}); + +const describableHalve: DescribableNumberOperation = Object.assign(halve, { + description: 'This operation halves the number.', +}); + +console.log(describeAndApply(describableDouble, 10)); // Beschreibung, dann 20 +console.log(describeAndApply(describableHalve, 10)); // Beschreibung, dann 5 +console.log(describeAndApply(describableDouble, -3)); // Beschreibung, dann -6 +console.log(describeAndApply(describableHalve, 7)); // Beschreibung, dann 3.5 +console.log(double(0)); // => 0 +console.log(halve(0)); // => 0 diff --git a/05_typescript/uebungen/u21_fn-identity/assets/js/bundle.js b/05_typescript/uebungen/u21_fn-identity/assets/js/bundle.js new file mode 100644 index 0000000..96fc186 --- /dev/null +++ b/05_typescript/uebungen/u21_fn-identity/assets/js/bundle.js @@ -0,0 +1,10 @@ +(() => { + // src/main.ts + var identity = (arg) => { + return arg; + }; + console.log(identity(42)); + console.log(identity("TS sucks")); + console.log(identity(["hello", "world"])); + console.log(identity(["hello", "world"])); +})(); diff --git a/05_typescript/uebungen/u21_fn-identity/package.json b/05_typescript/uebungen/u21_fn-identity/package.json index 8427e8d..7b5c966 100644 --- a/05_typescript/uebungen/u21_fn-identity/package.json +++ b/05_typescript/uebungen/u21_fn-identity/package.json @@ -9,5 +9,5 @@ "keywords": [], "author": "", "license": "ISC", - "type": "commonjs" + "type": "module" } diff --git a/05_typescript/uebungen/u21_fn-identity/src/main.ts b/05_typescript/uebungen/u21_fn-identity/src/main.ts index 121ac97..cdbb7f4 100644 --- a/05_typescript/uebungen/u21_fn-identity/src/main.ts +++ b/05_typescript/uebungen/u21_fn-identity/src/main.ts @@ -5,11 +5,18 @@ // Anweisungen: // 1 Implementiere eine generische identity Funktion, die einen Parameter vom Typ T annimmt und denselben Wert zurückgibt. +const identity = (arg: T): T => { + return arg; +}; // 2 Rufe identity mit einer number auf und speichere das Ergebnis. +console.log(identity(42)); // 3 Rufe identity mit einer string auf und speichere das Ergebnis. +console.log(identity('TS sucks')); // 4 Rufe identity mit einem Array von Objekten auf und speichere das Ergebnis. +console.log(identity(['hello', 'world'])); // 5 Stelle sicher, dass TypeScript die Rückgabetypen ohne explicit Type Annotations korrekt herleitet. +console.log(identity(['hello', 'world'])); diff --git a/05_typescript/unterricht/tag31/01_ts-narrowing-guards/assets/js/05_kontrollflussanalyse.js b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/assets/js/05_kontrollflussanalyse.js index 9428cf2..40ec802 100644 --- a/05_typescript/unterricht/tag31/01_ts-narrowing-guards/assets/js/05_kontrollflussanalyse.js +++ b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/assets/js/05_kontrollflussanalyse.js @@ -17,6 +17,9 @@ if (typeof value === "string") { return `String: ${value}`; } + if (Array.isArray(value)) { + return `String: ${value.join(", ")}`; + } return `Number: ${value.toFixed(2)}`; }; console.log(checkValue("hello")); diff --git a/05_typescript/unterricht/tag31/01_ts-narrowing-guards/assets/js/06_type-predicate.js b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/assets/js/06_type-predicate.js index f995964..98937fa 100644 --- a/05_typescript/unterricht/tag31/01_ts-narrowing-guards/assets/js/06_type-predicate.js +++ b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/assets/js/06_type-predicate.js @@ -4,6 +4,7 @@ const isFish = (pet2) => { return Object.hasOwn(pet2, "swim"); }; + const isBird = (pet2) => "fly" in pet2; const handlePet = (pet2) => { if (isFish(pet2)) { pet2.swim(); @@ -23,6 +24,8 @@ { swim: () => console.log("Another Fish flying") } ]; const fishes = zoo.filter((pet2) => isFish(pet2)); + const birds = zoo.filter(isBird); fishes.forEach((fish) => fish.swim()); + birds.forEach((bird) => bird.fly()); } })(); diff --git a/05_typescript/unterricht/tag31/01_ts-narrowing-guards/src/04_in-operator.ts b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/src/04_in-operator.ts index 45bfd6f..9fc0721 100644 --- a/05_typescript/unterricht/tag31/01_ts-narrowing-guards/src/04_in-operator.ts +++ b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/src/04_in-operator.ts @@ -14,7 +14,7 @@ // vehicle.drive(); // Property 'drive' does not exist on type 'Car | Boat'. // Object.hasOwn() führt kein narrowing aus | grenzt nicht den Datentyp ein - // if (Object.hasOwn(vehicle, 'drive')) { + //if (Object.hasOwn(vehicle, 'drive')) { if ('drive' in vehicle) { vehicle.drive(); } else { diff --git a/05_typescript/unterricht/tag31/01_ts-narrowing-guards/src/05_kontrollflussanalyse.ts b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/src/05_kontrollflussanalyse.ts index 66b4791..ddaf0c0 100644 --- a/05_typescript/unterricht/tag31/01_ts-narrowing-guards/src/05_kontrollflussanalyse.ts +++ b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/src/05_kontrollflussanalyse.ts @@ -21,11 +21,14 @@ Type Narrowing wird verwendet, um den Typ einer Variablen zu beschränken, wenn // Kontrollfluss mit Early Returns - const checkValue = (value: string | number): string => { + const checkValue = (value: string | number | number[]): string => { // Guard if (typeof value === 'string') { return `String: ${value}`; // early return bei Narrowing } + if (Array.isArray(value)) { + return `String: ${value.join(', ')}`; + } return `Number: ${value.toFixed(2)}`; }; diff --git a/05_typescript/unterricht/tag31/01_ts-narrowing-guards/src/06_type-predicate.ts b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/src/06_type-predicate.ts index 0740dd7..995c50f 100644 --- a/05_typescript/unterricht/tag31/01_ts-narrowing-guards/src/06_type-predicate.ts +++ b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/src/06_type-predicate.ts @@ -17,6 +17,7 @@ WICHTIG: "Außerdem grenzt es den Typ der Variablen auf der Grundlage des Ergebn // return 'swim' in pet; // in Operator führt Type-Narrowing durch }; + const isBird = (pet: Fish | Bird): pet is Bird => 'fly' in pet; const handlePet = (pet: Fish | Bird) => { // Property 'swim' does not exist on type 'Fish | Bird'. @@ -52,6 +53,8 @@ WICHTIG: "Außerdem grenzt es den Typ der Variablen auf der Grundlage des Ergebn ]; const fishes = zoo.filter((pet) => isFish(pet)); + const birds = zoo.filter(isBird); fishes.forEach((fish) => fish.swim()); + birds.forEach((bird) => bird.fly()); }