This commit is contained in:
Philippe Torrel
2026-10-19 14:31:58 +02:00
parent 73de568a05
commit 16416a0239
42 changed files with 1716 additions and 2 deletions
+2 -2
View File
@@ -517,7 +517,7 @@ Projekt 1: TaskManager
**Übungen:**
Übungen 12 - 20
Übungen 12 - 21
---
@@ -531,7 +531,7 @@ Projekt 1: TaskManager
**Übungen:**
Übungen 21 - 31
Übungen 22 - 31
Projektarbeit
---
@@ -0,0 +1,45 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Übung 12: Implementiere eine Type Guard Funktion</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
<script src="assets/js/bundle.js" defer></script>
</head>
<body>
<main>
<div class="container py-5">
<div class="alert alert-primary">
<h2>Übung 12: Implementiere eine Type Guard Funktion</h2>
<p>
Schreibe eine TypeScript-Funktion namens <code>formatInput</code>, die einen Parameter
<code>input</code> akzeptiert, der vom Typ <code>number</code>, <code>string</code> oder
<code>boolean</code>
sein kann. Die Funktion sollte einen formatierten String zurückgeben, der auf dem Typ der Eingabe basiert:
</p>
<ul class="list">
<li>
Wenn <code>input</code> eine <code>number</code> ist, gibst du die Zahl multipliziert mit
<code>100</code> als <code>string</code> zurück.
</li>
<li>
Wenn <code>input</code> ein <code>string</code> ist, wird
<code>string</code>
in Kleinbuchstaben zurückgegeben.
</li>
<li>
Wenn <code>input</code> eine <code>boolean</code> ist, gib "Yes" zurück, wenn <code>input</code> eine
<code>true</code> ist, und "No", wenn <code>input</code> eine <code>false</code> ist.
</li>
</ul>
<p>
Verwende den <code>typeof</code> Operator, um die Typen innerhalb der Funktion einzugrenzen.
<br />
Kopiere den Code unten und füge ihn ein, um deine Implementierung zu testen.
</p>
</div>
</div>
</main>
</body>
</html>
@@ -0,0 +1,13 @@
{
"name": "12_type-guard",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"ts": "npx esbuild src/main.ts --watch --bundle --outfile=assets/js/bundle.js --loader:.ts=ts"
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "commonjs"
}
@@ -0,0 +1,19 @@
console.log(formatInput(0.5)); // => "50"
console.log(formatInput(12)); // => "1200"
console.log(formatInput('Hello')); // => "hello"
console.log(formatInput('WORLD')); // => "world"
console.log(formatInput(true)); // => "Yes"
console.log(formatInput(false)); // => "No"
// Übung 12: Implementiere eine Type Guard Funktion
// Schreibe eine TypeScript-Funktion namens formatInput, die einen Parameter input akzeptiert, der vom Typ number, string oder boolean sein kann. Die Funktion sollte einen formatierten String zurückgeben, der auf dem Typ der Eingabe basiert:
// Wenn input eine number ist, gibst du die Zahl multipliziert mit 100 als string zurück.
// Wenn input ein string ist, wird string in Kleinbuchstaben zurückgegeben.
// Wenn input eine boolean ist, gib "Yes" zurück, wenn input eine true ist, und "No", wenn input eine false ist.
// Verwende den typeof Operator, um die Typen innerhalb der Funktion einzugrenzen.
// Kopiere den Code unten und füge ihn ein, um deine Implementierung zu testen.
@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Übung 13: Implementierung der Truthiness Narrowing in einer Funktion</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
<script src="assets/js/bundle.js" defer></script>
</head>
<body>
<main>
<div class="container py-5">
<div class="alert alert-primary">
<h2>Übung 13: Implementierung der Truthiness Narrowing in einer Funktion</h2>
<p>
Schreibe eine TypeScript-Funktion namens <code>displayStatus</code>, die einen Parameter
<code>status</code> akzeptiert, der ein <code>string</code>, <code>null</code> oder
<code>undefined</code> sein kann. Die Funktion sollte:
</p>
<ul class="list">
<li>Wenn <code>status</code> truthy ist, wird die Zeichenfolge "Status: ", verkettet mit Status.</li>
<li>
Wenn <code>status</code> fehlerhaft ist, wird die Zeichenfolge "No status available." zurückgegeben.
</li>
</ul>
<p>Verwende die Truthiness Narrowing, um zu prüfen, ob der Status truthy oder falsch ist.</p>
</div>
</div>
</main>
</body>
</html>
@@ -0,0 +1,13 @@
{
"name": "13_narrowing",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"ts": "npx esbuild src/main.ts --watch --bundle --outfile=assets/js/bundle.js --loader:.ts=ts"
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "commonjs"
}
@@ -0,0 +1,17 @@
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.
@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Übung 14: Equality Narrowing in einer Funktion implementieren</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
<script src="assets/js/bundle.js" defer></script>
</head>
<body>
<main>
<div class="container py-5">
<div class="alert alert-primary">
<h2>Übung 14: Equality Narrowing in einer Funktion implementieren</h2>
<p>
Gegeben ist eine unvollständige Funktion <code>analyzeInput</code><br />
Vervollständige die Funktion analyzeInput so, dass sie zurückgegeben wird:
</p>
<ul class="list">
<li>"Input is exactly true" wenn input === true.</li>
<li>"Input is exactly false" wenn input === false.</li>
<li>"Input is zero" wenn input === 0.</li>
<li>"Input is a positive number" wenn input eine Zahl größer als null ist.</li>
<li>"Input is a negative number" wenn input eine Zahl kleiner als null ist.</li>
<li>"Input is the string 'hello'" wenn input === "hello".</li>
<li>"Input is another string" wenn input irgendein anderer String ist.</li>
<li>"Unknown input" andernfalls.</li>
</ul>
<p>Verwende Equality- und Vergleichsoperatoren, um den Typ und den Wert der Eingabe einzugrenzen.</p>
</div>
</div>
</main>
</body>
</html>
@@ -0,0 +1,13 @@
{
"name": "14_narrowing-equality",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"ts": "npx esbuild src/main.ts --watch --bundle --outfile=assets/js/bundle.js --loader:.ts=ts"
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "commonjs"
}
@@ -0,0 +1,35 @@
const analyzeInput = (input: string | number | boolean): string => {
// Your code here
};
console.log(analyzeInput(true)); // => "Input is exactly true"
console.log(analyzeInput(false)); // => "Input is exactly false"
console.log(analyzeInput(0)); // => "Input is zero"
console.log(analyzeInput(42)); // => "Input is a positive number"
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"
// Übung 14: Equality Narrowing in einer Funktion implementieren
// Vervollständige die Funktion analyzeInput so, dass sie zurückgegeben wird:
// "Input is exactly true" wenn input === true.
// "Input is exactly false" wenn input === false.
// "Input is zero" wenn input === 0.
// "Input is a positive number" wenn input eine Zahl größer als null ist.
// "Input is a negative number" wenn input eine Zahl kleiner als null ist.
// "Input is the string 'hello'" wenn input === "hello".
// "Input is another string" wenn input irgendein anderer String ist.
// "Unknown input" andernfalls.
// Verwende Equality- und Vergleichsoperatoren, um den Typ und den Wert der Eingabe einzugrenzen.
@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Übung 15: Verwendung des in-Operators zur Type Narrowing in TypeScript</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
<script src="assets/js/bundle.js" defer></script>
</head>
<body>
<main>
<div class="container py-5">
<div class="alert alert-primary">
<h2>Übung 15: Verwendung des in-Operators zur Type Narrowing in TypeScript</h2>
<p>
Erstelle eine TypeScript-Funktion mit dem Namen <code>play</code>, die einen Parameter vom Typ
<code>Guitar | Piano</code> annimmt. Der Typ <code>Guitar</code> hat eine Methode <code>strum</code>, und
der Typ Piano hat eine Methode <code>pressKeys</code>.
</p>
<p>
In der Funktion <code>play</code> verwendest du den Operator <code>in</code>, um festzustellen, ob das
übergebene instrument ein <code>Guitar</code> oder ein <code>Piano</code> ist, und rufst dann die
entsprechende Methode auf. Achte darauf, dass deine Funktion beide Typen richtig behandelt.
</p>
</div>
</div>
</main>
</body>
</html>
@@ -0,0 +1,13 @@
{
"name": "15_narrowing-in-operator",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"ts": "npx esbuild src/main.ts --watch --bundle --outfile=assets/js/bundle.js --loader:.ts=ts"
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "commonjs"
}
@@ -0,0 +1,14 @@
type Guitar = { strum: () => void };
type Piano = { pressKeys: () => void };
const play = (instrument: Guitar | Piano) => {
// Your code here
};
// Create guitar instance
// Create piano instance
// Call functions
play(guitar); // => "Strumming the guitar!"
play(piano); // => "Pressing piano keys!"
@@ -0,0 +1,44 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Übung 16: Type Narrowing mit Zuweisungsoperationen</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
<script src="assets/js/bundle.js" defer></script>
</head>
<body>
<main>
<div class="container py-5">
<div class="alert alert-primary">
<h2>Übung 16: Type Narrowing mit Zuweisungsoperationen</h2>
<p>
In dieser Übung arbeitest du mit TypeScripts Features zur Type Narrowing durch Zuweisungsoperationen. Du
definierst eine Variable mit einem Union Type <code>(string | number | boolean)</code> und demonstrierst,
wie TypeScript den Typ dynamisch auf Basis der zugewiesenen Werte einschränkt.
</p>
<p>
Du wirst auch eine Funktion implementieren, die einen Union Type Parameter akzeptiert und diesen korrekt
behandelt, indem du die TypeScript-Funktionen fürs Type Narrowing nutzt.
</p>
<h4>Anweisungen:</h4>
<ol class="list">
<li>
Schreibe eine Funktion handleValue, die einen <code>string | number | boolean</code> Parameter annimmt und
je nach Typ des Arguments ein anderes Verhalten protokolliert.
<ul class="list">
<li>Wenn es eine <code>string</code> ist, protokolliere die Version in Großbuchstaben.</li>
<li>Wenn es sich um eine <code>number</code> handelt, logge ihren Wert multipliziert mit 2.</li>
<li>
Wenn es eine <code>boolean</code> ist, protokolliere "It's true!" oder "It's false!". Verwende einen
ternären Operator.
</li>
</ul>
</li>
<li>Teste die Funktion mit verschiedenen Eingaben.</li>
</ol>
</div>
</div>
</main>
</body>
</html>
@@ -0,0 +1,13 @@
{
"name": "16_narrowing-zuweisung",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"ts": "npx esbuild src/main.ts --watch --bundle --outfile=assets/js/bundle.js --loader:.ts=ts"
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "commonjs"
}
@@ -0,0 +1,25 @@
// 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!"
// Übung 16: Type Narrowing mit Zuweisungsoperationen
// In dieser Übung arbeitest du mit TypeScripts Features zur Type Narrowing durch Zuweisungsoperationen. Du definierst eine Variable mit einem Union Type (string | number | boolean) und demonstrierst, wie TypeScript den Typ dynamisch auf Basis der zugewiesenen Werte einschränkt.
// Du wirst auch eine Funktion implementieren, die einen Union Type Parameter akzeptiert und diesen korrekt behandelt, indem du die TypeScript-Funktionen fürs Type Narrowing nutzt.
// Anweisungen:
// 1Schreibe 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 sich um eine number handelt, logge ihren Wert multipliziert mit 2.
// Wenn es eine boolean ist, protokolliere "It's true!" oder "It's false!". Verwende einen ternären Operator.
// 2Teste die Funktion mit verschiedenen Eingaben.
@@ -0,0 +1,48 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Übung 17: Kontrollflussanalyse und Type Narrowing</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
<script src="assets/js/bundle.js" defer></script>
</head>
<body>
<main>
<div class="container py-5">
<div class="alert alert-primary">
<h2>Übung 17: Kontrollflussanalyse und Type Narrowing</h2>
<p>
In dieser Übung erstellst du eine Funktion, die einen Union Type Parameter akzeptiert und demonstriert, wie
TypeScript automatisch eine Type Narrowing basierend auf dem Kontrollfluss durchführt.
</p>
<p>
Du wirst Bedingungen implementieren, um verschiedene Typen zu behandeln und je nach Typ der Eingabe
unterschiedliche Ergebnisse zurückzugeben. Ziel ist es, die Verwendung der TypeScript Kontrollflussanalyse
zu üben, um Typsicherheit ohne unnötiges Type-Checking zu gewährleisten.
</p>
<h4>Anweisungen:</h4>
<ol class="list">
<li>
Erstelle eine Funktion handleInput, die einen Parameter vom Typ string | number | boolean | null
akzeptiert.
</li>
<li>
Verwende innerhalb der Funktion die Blöcke if, else if und else, um verschiedene Typen zu behandeln:
<ul class="list">
<li>Wenn die input null ist, gibst du "No value provided" zurück.</li>
<li>Wenn die input eine boolean ist, wird "True" oder "False" zurückgegeben.</li>
<li>Wenn input eine string ist, wird die Großbuchstabenversion der Zeichenkette zurückgegeben.</li>
<li>Wenn input eine number ist, wird das Quadrat der Zahl zurückgegeben.</li>
</ul>
</li>
<li>
Teste die Funktion mit verschiedenen Eingaben, um zu überprüfen, ob TypeScript die Typen korrekt
eingrenzt.
</li>
</ol>
</div>
</div>
</main>
</body>
</html>
@@ -0,0 +1,13 @@
{
"name": "17_narrowing-kontrollfluss",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"ts": "npx esbuild src/main.ts --watch --bundle --outfile=assets/js/bundle.js --loader:.ts=ts"
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "commonjs"
}
@@ -0,0 +1,27 @@
// 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
// In dieser Übung erstellst du eine Funktion, die einen Union Type Parameter akzeptiert und demonstriert, wie TypeScript automatisch eine Type Narrowing basierend auf dem Kontrollfluss durchführt.
// Du wirst Bedingungen implementieren, um verschiedene Typen zu behandeln und je nach Typ der Eingabe unterschiedliche Ergebnisse zurückzugeben. Ziel ist es, die Verwendung der TypeScript Kontrollflussanalyse zu üben, um Typsicherheit ohne unnötiges Type-Checking zu gewährleisten.
// Anweisungen:
// 1 Erstelle eine Funktion handleInput, die einen Parameter vom Typ string | number | boolean | null akzeptiert.
// 2 Verwende innerhalb der Funktion die Blöcke if, else if und else, um verschiedene Typen zu behandeln:
// Wenn die input null ist, gibst du "No value provided" zurück.
// Wenn die input eine boolean ist, wird "True" oder "False" zurückgegeben.
// Wenn input eine string ist, wird die Großbuchstabenversion der Zeichenkette zurückgegeben.
// Wenn input eine number ist, wird das Quadrat der Zahl zurückgegeben.
// 3 Teste die Funktion mit verschiedenen Eingaben, um zu überprüfen, ob TypeScript die Typen korrekt eingrenzt.
@@ -0,0 +1,50 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Übung 18: Type Predicates implementieren</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
<script src="assets/js/bundle.js" defer></script>
</head>
<body>
<main>
<div class="container py-5">
<div class="alert alert-primary">
<h2>Übung 18: Type Predicates implementieren</h2>
<p>
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.
</p>
<h4>Anweisungen:</h4>
<ol class="list">
<li>
Definiere zwei Typen, Car und Truck, wobei:
<ul>
<li>Car hat eine Methode drive().</li>
<li>Truck hat eine Methode loadCargo().</li>
</ul>
</li>
<li>
Erstelle eine Type Predicate Funktion isCar, um zu prüfen, ob ein bestimmtes Fahrzeug ein Car ist und eine
Fahrfunktion hat. Hinweis: .drive !== undefined.
</li>
<li>
Implementiere eine Funktion handleVehicle, die einen Parameter vom Typ Car | Truck akzeptiert:
<ul class="list">
<li>Wenn das Fahrzeug ein Car ist, rufe drive() an.</li>
<li>Wenn das Fahrzeug ein Truck ist, rufe loadCargo() an.</li>
</ul>
</li>
<li>
Erstelle ein Array von Car | Truck Objekten und filtere nur die Autos mit dem isCar Predicate heraus.
</li>
<li>Teste deine Funktionen mit verschiedenen Eingaben.</li>
</ol>
</div>
</div>
</main>
</body>
</html>
@@ -0,0 +1,13 @@
{
"name": "18_type-predicates",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"ts": "npx esbuild src/main.ts --watch --bundle --outfile=assets/js/bundle.js --loader:.ts=ts"
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "commonjs"
}
@@ -0,0 +1,30 @@
// 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.
// Anweisungen:
// 1 Definiere zwei Typen, Car und Truck, wobei:
// Car hat eine Methode drive().
// Truck hat eine Methode loadCargo().
// 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.
// 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.
// 4 Erstelle ein Array von Car | Truck Objekten und filtere nur die Autos mit dem isCar Predicate heraus.
// 5 Teste deine Funktionen mit verschiedenen Eingaben.
@@ -0,0 +1,50 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Übung 19: Arbeiten mit Function Type Expressions</title>
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.7/dist/css/bootstrap.min.css"
rel="stylesheet" />
<script src="assets/js/bundle.js" defer></script>
</head>
<body>
<main>
<div class="container py-5">
<div class="alert alert-primary">
<h2>Übung 19: Arbeiten mit Function Type Expressions</h2>
<p>
In dieser Aufgabe schreibst du eine Funktion, die andere Funktionen
als Parameter akzeptiert und Logik basierend auf diesen Function
Type Expressions implementiert.
</p>
<h4>Anweisungen:</h4>
<ol class="list">
<li>
Definiere einen Type Alias <code>MathOperation</code> für eine
Funktion, die zwei <code>numbers</code> als Parameter nimmt und
einen <code>number</code> zurückgibt.
</li>
<li>
Implementiere eine Funktion <code>calculate</code>, die eine
Funktion vom Typ <code>MathOperation</code> und zwei
<code>numbers</code>
annimmt und die Funktion auf die Zahlen anwendet.
</li>
<li>
Erstelle zwei neue Funktionen, <code>add</code> und
<code>multiply</code>, die der Signatur
<code>MathOperation</code> entsprechen.
</li>
<li>
Teste alle Funktionen, indem du geeignete Argumente übergibst und
die Ergebnisse protokollierst.
</li>
</ol>
</div>
</div>
</main>
</body>
</html>
@@ -0,0 +1,13 @@
{
"name": "19_fn-typausdruecke",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"ts": "npx esbuild src/main.ts --watch --bundle --outfile=assets/js/bundle.js --loader:.ts=ts"
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "commonjs"
}
@@ -0,0 +1,17 @@
// 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.
// Anweisungen:
// 1 Definiere einen Type Alias MathOperation für eine Funktion, die zwei numbers als Parameter nimmt und einen number zurückgibt.
// 2 Implementiere eine Funktion calculate, die eine Funktion vom Typ MathOperation und zwei numbers annimmt und die Funktion auf die Zahlen anwendet.
// 3 Erstelle zwei neue Funktionen, add und multiply, die der Signatur MathOperation entsprechen.
// 4 Teste alle Funktionen, indem du geeignete Argumente übergibst und die Ergebnisse protokollierst.
@@ -0,0 +1,62 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Übung 20: Call Signatures für Zahlenoperationen</title>
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.7/dist/css/bootstrap.min.css"
rel="stylesheet" />
<script src="assets/js/bundle.js" defer></script>
</head>
<body>
<main>
<div class="container py-5">
<div class="alert alert-primary">
<h2>Übung 20: Call Signatures für Zahlenoperationen</h2>
<p>
In dieser Übung erstellst und verwendest du ein paar einfache
Funktionen, die sich an bestimmte Call Signatures für die Arbeit mit
Zahlen halten.
</p>
<h4>Anweisungen:</h4>
<ol class="list">
<li>
<strong>Definiere eine Funktion vom Typ</strong>
<code>NumberOperation</code>, die ein einzelnes
<code>number</code> annimmt und ein
<code>number</code> zurückgibt.
</li>
<li>
<strong>Implementiere zwei Funktionen</strong>,
<code>double</code> und <code>halve</code>, die der Call Signature
<code>NumberOperation</code> folgen:
<ul class="list">
<li>
<code>double</code>: Multipliziert die eingegebene Zahl mit 2.
</li>
<li><code>halve</code>: Teilt die eingegebene Zahl durch 2.</li>
</ul>
</li>
<li>
<strong>Definiere einen Objekttyp</strong>
<code>DescribableNumberOperation</code> mit einer
description-Property vom Typ <code>string</code> und einer Cal
Signature, die <code>NumberOperation</code> entspricht.
</li>
<li>
<strong>Implementiere eine Funktion</strong>
<code>describeAndApply</code>, die ein
<code>DescribableNumberOperation</code>
Objekt annimmt, dessen <code>description</code> protokolliert und
die Operation auf eine bestimmte Zahl anwendet.
</li>
<li><strong>Teste alle Funktionen</strong> mit ein paar Zahlen.</li>
</ol>
</div>
</div>
</main>
</body>
</html>
@@ -0,0 +1,13 @@
{
"name": "20_fn-call-signatures",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"ts": "npx esbuild src/main.ts --watch --bundle --outfile=assets/js/bundle.js --loader:.ts=ts"
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "commonjs"
}
@@ -0,0 +1,38 @@
// 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.
// Anweisungen:
// 1 Definiere eine Funktion vom Typ NumberOperation, die ein einzelnes number annimmt und ein number zurückgibt.
// 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.
// 3 Definiere einen Objekttyp DescribableNumberOperation mit einer description-Property vom Typ string und einer Cal Signature, die NumberOperation entspricht.
// 4 Implementiere eine Funktion describeAndApply, die ein DescribableNumberOperation Objekt annimmt, dessen description protokolliert und die Operation auf eine bestimmte Zahl anwendet.
// 5 Teste alle Funktionen mit ein paar Zahlen.
@@ -0,0 +1,53 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Übung 21: Eine allgemeine Identitätsfunktion erstellen</title>
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.7/dist/css/bootstrap.min.css"
rel="stylesheet" />
<script src="assets/js/bundle.js" defer></script>
</head>
<body>
<main>
<div class="container py-5">
<div class="alert alert-primary">
<h2>Übung 21: Eine allgemeine Identitätsfunktion erstellen</h2>
<p>
In dieser Übung erstellst du eine einfache generische Funktion
namens <code>identity</code>, die den ihr übergebenen Wert
zurückgibt. So lernst du, wie generische Funktionen mit
verschiedenen Typen arbeiten können, ohne die Typsicherheit zu
verlieren.
</p>
<h4>Anweisungen:</h4>
<ol class="list">
<li>
Implementiere eine generische <code>identity</code> Funktion, die
einen Parameter vom Typ <code>T</code> annimmt und denselben Wert
zurückgibt.
</li>
<li>
Rufe <code>identity</code> mit einer <code>number</code> auf und
speichere das Ergebnis.
</li>
<li>
Rufe <code>identity</code> mit einer <code>string</code> auf und
speichere das Ergebnis.
</li>
<li>
Rufe <code>identity</code> mit einem Array von Objekten auf und
speichere das Ergebnis.
</li>
<li>
Stelle sicher, dass TypeScript die Rückgabetypen ohne explicit
Type Annotations korrekt herleitet.
</li>
</ol>
</div>
</div>
</main>
</body>
</html>
@@ -0,0 +1,13 @@
{
"name": "21_fn-identity",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"ts": "npx esbuild src/main.ts --watch --bundle --outfile=assets/js/bundle.js --loader:.ts=ts"
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "commonjs"
}
@@ -0,0 +1,15 @@
// Übung 21: Eine allgemeine Identitätsfunktion erstellen
// In dieser Übung erstellst du eine einfache generische Funktion namens identity, die den ihr übergebenen Wert zurückgibt. So lernst du, wie generische Funktionen mit verschiedenen Typen arbeiten können, ohne die Typsicherheit zu verlieren.
// Anweisungen:
// 1 Implementiere eine generische identity Funktion, die einen Parameter vom Typ T annimmt und denselben Wert zurückgibt.
// 2 Rufe identity mit einer number auf und speichere das Ergebnis.
// 3 Rufe identity mit einer string auf und speichere das Ergebnis.
// 4 Rufe identity mit einem Array von Objekten auf und speichere das Ergebnis.
// 5 Stelle sicher, dass TypeScript die Rückgabetypen ohne explicit Type Annotations korrekt herleitet.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

@@ -0,0 +1,43 @@
(() => {
// src/01_fn-type-expression.ts
{
let mathOperationFn = function(fn) {
return fn(4, 5);
}, multiplyFn = function(a, b) {
return a * b;
}, printToConsole = function(s) {
console.log(s);
}, mathOperation = function(fn) {
return fn(10, 20);
};
const multiply = (a, b) => {
return a * b;
};
const multiply2 = (a, b) => {
return a * b;
};
console.log(multiply(2, 4));
console.log(multiply2(2, 4));
mathOperationFn(multiplyFn);
const greeter = (fn) => {
fn("Hello, World");
};
const greeter2 = (fn) => {
fn("Hello, World");
};
greeter(printToConsole);
greeter2(printToConsole);
const logMessage = (message) => {
console.log(message);
};
const logMsg = (message) => {
console.log(message);
};
logMessage("Hello World");
logMsg("Hello World");
const subtract = (x, y) => {
return x - y;
};
console.log(mathOperation(subtract));
}
})();
@@ -0,0 +1,48 @@
(() => {
// src/02_fn-call-signature.ts
{
const sum = (a, b) => {
return `The sum is ${a + b}`;
};
const sum2 = (a, b) => {
return `The sum is ${a + b}`;
};
console.log(sum(40, 2));
console.log(sum2(60, 7));
const sum3 = (a = { a: 1, b: 2 }, b = 2) => {
return `The sum is ${a.a + b}`;
};
const add = (x, y) => {
return x + y;
};
const multiply = (x, y) => {
return x * y;
};
console.log(add(123, 321));
console.log(multiply(25, 25));
const person = {
name: "John",
age: 23,
walk() {
return "i'm walking.";
},
run(n) {
return `i'm running very fast (${n?.toFixed(1)}km/h).`;
}
};
console.log(person.walk());
console.log(person.run(100));
}
console.log("--- Describable Function ---");
{
let doSomething = function(fn, n = 6) {
console.log(fn.description + " returned " + fn(n));
};
const myFunc = (someArg) => {
return someArg > 3;
};
myFunc.description = "Default description";
doSomething(myFunc);
doSomething(myFunc, 2);
}
})();
@@ -0,0 +1,35 @@
(() => {
// src/03_fn-generics.ts
{
const identityNumber = (arg) => {
return arg;
};
const identityString = (arg) => {
return arg;
};
const identity = (arg) => {
return arg;
};
let resultNumber = identity(42);
let resultString = identity("Hello TypeScript");
let resultStr = identity("Hello TypeScript");
let resultBoolean = identity(true);
console.log(resultNumber, resultString, resultStr, resultBoolean);
const firstElement = (arr) => {
return arr[0];
};
console.log(firstElement(["Stefan", "Christian", "Florian", "Benjamin"]));
console.log(firstElement([23, 19, 5, 42, 2, 45]));
console.log(
firstElement([
{ firstName: "John", age: 27 },
{ firstName: "JAne", age: 18 }
])
);
console.log(firstElement([]));
let inferredResult = identity("Hello");
let explicitResult = identity(42);
console.log(inferredResult);
console.log(explicitResult);
}
})();
@@ -0,0 +1,25 @@
<!doctype html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>TypeScript - Grundlagen</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
<!-- <script src="assets/js/01_fn-type-expression.js" defer></script> -->
<script src="assets/js/02_fn-call-signature.js" defer></script>
</head>
<body>
<main>
<div class="container py-5">
<h1>TypeScript - Grundlagen</h1>
<p>
TypeScript ist eine von Microsoft entwickelte Skriptsprache, die auf den Vorschlägen zum ECMAScript-6-Standard
basiert und statische Typisierung zu JavaScript hinzufügt. Sprachkonstrukte von TypeScript, wie Klassen,
Vererbung, Module und anonyme Funktionen, wurden auch in ECMAScript 6 übernommen.
</p>
<img src="assets/img/what-is-ts.webp" alt="TypeScript Kreisdiagramm" class="img-thumbnail" />
</div>
</main>
</body>
</html>
@@ -0,0 +1,499 @@
{
"name": "01_ts-types",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "01_ts-types",
"version": "1.0.0",
"devDependencies": {
"esbuild": "^0.28.2"
}
},
"node_modules/@esbuild/aix-ppc64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz",
"integrity": "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"aix"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/android-arm": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.2.tgz",
"integrity": "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/android-arm64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz",
"integrity": "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/android-x64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.2.tgz",
"integrity": "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/darwin-arm64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz",
"integrity": "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/darwin-x64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz",
"integrity": "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/freebsd-arm64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz",
"integrity": "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/freebsd-x64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz",
"integrity": "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-arm": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz",
"integrity": "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-arm64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz",
"integrity": "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-ia32": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz",
"integrity": "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-loong64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz",
"integrity": "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==",
"cpu": [
"loong64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-mips64el": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz",
"integrity": "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==",
"cpu": [
"mips64el"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-ppc64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz",
"integrity": "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-riscv64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz",
"integrity": "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==",
"cpu": [
"riscv64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-s390x": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz",
"integrity": "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==",
"cpu": [
"s390x"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-x64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz",
"integrity": "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/netbsd-arm64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz",
"integrity": "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/netbsd-x64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz",
"integrity": "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openbsd-arm64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz",
"integrity": "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openbsd-x64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz",
"integrity": "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openharmony-arm64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz",
"integrity": "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openharmony"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/sunos-x64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz",
"integrity": "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"sunos"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-arm64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz",
"integrity": "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-ia32": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz",
"integrity": "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-x64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz",
"integrity": "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/esbuild": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz",
"integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"bin": {
"esbuild": "bin/esbuild"
},
"engines": {
"node": ">=18"
},
"optionalDependencies": {
"@esbuild/aix-ppc64": "0.28.2",
"@esbuild/android-arm": "0.28.2",
"@esbuild/android-arm64": "0.28.2",
"@esbuild/android-x64": "0.28.2",
"@esbuild/darwin-arm64": "0.28.2",
"@esbuild/darwin-x64": "0.28.2",
"@esbuild/freebsd-arm64": "0.28.2",
"@esbuild/freebsd-x64": "0.28.2",
"@esbuild/linux-arm": "0.28.2",
"@esbuild/linux-arm64": "0.28.2",
"@esbuild/linux-ia32": "0.28.2",
"@esbuild/linux-loong64": "0.28.2",
"@esbuild/linux-mips64el": "0.28.2",
"@esbuild/linux-ppc64": "0.28.2",
"@esbuild/linux-riscv64": "0.28.2",
"@esbuild/linux-s390x": "0.28.2",
"@esbuild/linux-x64": "0.28.2",
"@esbuild/netbsd-arm64": "0.28.2",
"@esbuild/netbsd-x64": "0.28.2",
"@esbuild/openbsd-arm64": "0.28.2",
"@esbuild/openbsd-x64": "0.28.2",
"@esbuild/openharmony-arm64": "0.28.2",
"@esbuild/sunos-x64": "0.28.2",
"@esbuild/win32-arm64": "0.28.2",
"@esbuild/win32-ia32": "0.28.2",
"@esbuild/win32-x64": "0.28.2"
}
}
}
}
@@ -0,0 +1,14 @@
{
"name": "02_ts-functions",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"ts": "npx esbuild \"src/*.ts\" --watch --bundle --outdir=\"assets/js\" --loader:.ts=ts"
},
"keywords": [],
"type": "module",
"devDependencies": {
"esbuild": "^0.28.2"
}
}
@@ -0,0 +1,83 @@
// Function Type Expression
/*
Eine Funktionstyp-Deklaration ist eine Möglichkeit, den Typ einer Funktion zu definieren.
Dabei werden die Typen ihrer Eingänge (Parameter) und ihres Ausgangs (Rückgabewert) definiert.
*/
{
type MathFn = (x: number, y: number) => number; // Funktionstyp-deklaration
function mathOperationFn(fn: MathFn): number {
return fn(4, 5);
}
function multiplyFn(a: number, b: number): number {
return a * b;
}
const multiply = (a: number, b: number): number => {
return a * b;
};
// Funktionsausdruck mit Funktionsannotation
const multiply2: MathFn = (a, b) => {
return a * b;
};
console.log(multiply(2, 4)); // => 8
console.log(multiply2(2, 4)); // => 8
mathOperationFn(multiplyFn); // => 20
//------
// Call Signature (a: string) => void
type greeterFn = (a: string) => void;
const greeter = (fn: (a: string) => void) => {
fn('Hello, World');
};
const greeter2 = (fn: greeterFn) => {
fn('Hello, World');
};
function printToConsole(s: string): void {
console.log(s);
}
greeter(printToConsole); // => "Hello, World"
greeter2(printToConsole); // => "Hello, World"
// ------
// Call Signature
const logMessage: (p: string) => void = (message) => {
console.log(message);
};
// RECOMMENDED Call Signature als Funktionstyp-Deklaration festlegen
type LogFn = (p: string) => void;
const logMsg: LogFn = (message) => {
console.log(message);
};
logMessage('Hello World');
logMsg('Hello World');
// -----
type MathFunction = (a: number, b: number) => number;
// In TypeScript kannst du einer klassischen function-Deklaration nicht direkt einen Funktions-Typ zuweisen.
function mathOperation(fn: MathFunction) {
return fn(10, 20);
}
const subtract: MathFunction = (x, y) => {
return x - y;
};
console.log(mathOperation(subtract)); // => -10
}
@@ -0,0 +1,91 @@
// Call Signatures
/*
Eine Call Signature ermöglicht es dir, die Art und Weise zu beschreiben, wie eine Funktion aufgerufen werden soll, indem du die Typen ihrer Parameter und ihren Rückgabetyp auf eine wiederverwendbare Weise festlegst. Dies ist besonders nützlich, wenn du konsistente Funktionstypen erstellen möchtest, die in deiner gesamten Codebasis angewendet werden können.
*/
{
// (a: number, b: number) => string -> is a "call signature"
type SumFn = (p1: number, p2: number) => string;
const sum: SumFn = (a, b) => {
return `The sum is ${a + b}`;
};
const sum2 = (a: number, b: number): string => {
return `The sum is ${a + b}`;
};
console.log(sum(40, 2)); // => 'The sum is 42'
console.log(sum2(60, 7)); // => 'The sum is 67'
// ------
// EMPFEHLUNG: call signature und type annotation von einander trennen und call signature in type alias oder interface definieren.
const sum3: (a: { a: number; b: number }, b: number) => string = (
a: { a: number; b: number } = { a: 1, b: 2 },
b: number = 2,
): string => {
return `The sum is ${a.a + b}`;
};
type Operation = (x: number, y: number) => number;
const add: Operation = (x, y) => {
return x + y;
};
const multiply: Operation = (x, y) => {
return x * y;
};
console.log(add(123, 321)); //=> 444
console.log(multiply(25, 25)); //=> 625
//--------
type Person = {
name: string;
age: number;
walk: (speed?: number) => string;
run(speed?: number): string;
};
const person: Person = {
name: 'John',
age: 23,
walk() {
return "i'm walking.";
},
run(n) {
return `i'm running very fast (${n?.toFixed(1)}km/h).`;
},
};
console.log(person.walk());
console.log(person.run(100));
}
//--------
console.log('--- Describable Function ---');
//--------
{
// VORSICHT SONDERFALL in der Signatur bei describable Function
// Bei Describable Function : anstatt => für Rückgabe
type DescribableFunction = {
description: string;
(someArg: number): boolean; // Call signature
};
function doSomething(fn: DescribableFunction, n = 6) {
console.log(fn.description + ' returned ' + fn(n));
}
const myFunc = (someArg: number): boolean => {
return someArg > 3;
};
myFunc.description = 'Default description';
doSomething(myFunc); // => "Default description returned true"
doSomething(myFunc, 2); // => "Default description returned false"
}
@@ -0,0 +1,63 @@
// Generic Functions
/*
In TypeScript werden Funktionen durch die Verwendung von Generics noch leistungsfähiger und flexibler. Generics ermöglichen es uns, wiederverwendbare Funktionen zu erstellen, die mit einer Vielzahl von Typen arbeiten können und dabei die Sicherheit und Vorhersagbarkeit des Typsystems von TypeScript beibehalten.
Diese Flexibilität ermöglicht es Entwicklern, vielseitigeren und besser wartbaren Code zu schreiben, ohne die Typsicherheit zu opfern.
*/
{
// const identity = (arg: number | string): number | string => {
// // code logic which can handle different data types
// return arg;
// };
const identityNumber = (arg: number): number => {
// code logic which can handle different data types
return arg;
};
const identityString = (arg: string): string => {
// code logic which can handle different data types
return arg;
};
// Generic Function
const identity = <T>(arg: T): T => {
// code logic with different types
return arg;
};
let resultNumber = identity(42); // T is number
let resultString = identity('Hello TypeScript'); // T is string
let resultStr = identity<string>('Hello TypeScript'); // T is string
let resultBoolean = identity<boolean>(true); // T is boolean
console.log(resultNumber, resultString, resultStr, resultBoolean);
// ---------------
// const firstElement = (arr: any[]) => {
// return arr[0];
// };
const firstElement = <T>(arr: T[]): T => {
return arr[0];
};
console.log(firstElement<string>(['Stefan', 'Christian', 'Florian', 'Benjamin'])); // => 'Stefan' <- string
console.log(firstElement<number>([23, 19, 5, 42, 2, 45])); // => 23 <- number
console.log(
firstElement([
{ firstName: 'John', age: 27 },
{ firstName: 'JAne', age: 18 },
]),
); // => {...} <- object
console.log(firstElement([])); // => undefined
// ---
let inferredResult = identity('Hello'); // TypeScript infers that T is string
let explicitResult = identity<number>(42); // Explicitly sets T to number
console.log(inferredResult);
console.log(explicitResult);
}