This commit is contained in:
Philippe Torrel
2026-07-30 14:29:28 +02:00
parent 14c22e4b18
commit e375bf23bc
88 changed files with 3891 additions and 141 deletions

View File

@@ -510,3 +510,32 @@ Projekte + weiteres Modul einbinden
**Übungen:**
Übungen 10 - 18
---
### Tag 34
**Inhalt:**
- TS Funktionen und Objekte
- Abschluss TypeScript Grundlagen
- Abschlussquiz
**Übungen:**
Übungen 19 - 31
Projektarbeit
---
### Tag 35
**Inhalt:**
- Projekt-Webseite in TS
- Optimierung mit KI
- 1:1 Meeting
**Übungen:**
Projektarbeit

View File

@@ -0,0 +1,34 @@
(() => {
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 setStatus = (status) => {
console.log(status);
};
const rateExperience = (rating) => {
return `You rated the experience as ${rating}`;
};
const togglePower = (state) => {
return state ? "Power is on" : "Power is off";
};
setStatus("success");
setStatus("error");
console.log(rateExperience(5));
console.log(rateExperience(3));
console.log(togglePower(true));
console.log(togglePower(false));
}
}
});
require_main();
})();

View File

@@ -1,30 +1,45 @@
// [ ] Step 1: Create a function 'setStatus' that accepts a string literal type parameter 'status'.
{
// [x] Step 1: Create a function 'setStatus' that accepts a string literal type parameter 'status'.
// - The 'status' can only be "success", "error", or "loading".
// - The function should log the status to the console.
// [ ] Step 2: Create a function 'rateExperience' that accepts a numeric literal type parameter 'rating'.
const setStatus = (status: 'success' | 'error' | 'loading'): void => {
console.log(status);
};
// [x] Step 2: Create a function 'rateExperience' that accepts a numeric literal type parameter 'rating'.
// - The 'rating' can only be 1, 2, 3, 4, or 5.
// - The function should return a message indicating the rating.
type Rating = 1 | 2 | 3 | 4 | 5;
// [ ] Step 3: Create a function 'togglePower' that accepts a boolean literal type parameter 'state'.
const rateExperience = (rating: Rating): string => {
return `You rated the experience as ${rating}`;
};
// [x] Step 3: Create a function 'togglePower' that accepts a boolean literal type parameter 'state'.
// - The 'state' can only be true or false.
// - The function should return a message indicating whether the power is ON or OFF.
// [ ] Step 4: Test the functions with valid and invalid values to ensure the correct behavior and type safety.
const togglePower = (state: boolean) => {
return state ? 'Power is on' : 'Power is off';
};
// [x] Step 4: Test the functions with valid and invalid values to ensure the correct behavior and type safety.
// Test cases (students should verify that these work as expected)
// Test 'setStatus' function
setStatus('success'); // OK
setStatus('error'); // OK
setStatus('complete'); // Error: Argument of type '"complete"' is not assignable to parameter of type '"success" | "error" | "loading"'.
//setStatus('complete'); // Error: Argument of type '"complete"' is not assignable to parameter of type '"success" | "error" | "loading"'.
// Test 'rateExperience' function
console.log(rateExperience(5)); // => "You rated the experience as 5"
console.log(rateExperience(3)); // => "You rated the experience as 3"
console.log(rateExperience(6)); // Error: Argument of type '6' is not assignable to parameter of type '1 | 2 | 3 | 4 | 5'.
//console.log(rateExperience(6)); // Error: Argument of type '6' is not assignable to parameter of type '1 | 2 | 3 | 4 | 5'.
// Test 'togglePower' function
console.log(togglePower(true)); // => "Power is ON"
console.log(togglePower(false)); // => "Power is OFF"
console.log(togglePower('on')); // Error: Argument of type '"on"' is not assignable to parameter of type 'true | false'.
//console.log(togglePower('on')); // Error: Argument of type '"on"' is not assignable to parameter of type 'true | false'.
}

View File

@@ -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 formatInput = (input) => {
switch (typeof input) {
case "number":
return String(input * 100);
case "string":
return input.toLowerCase();
case "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();
})();

View File

@@ -1,19 +1,34 @@
{
// Ü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:
const formatInput = (input: number | string | boolean): string => {
switch (typeof input) {
case 'number':
return String(input * 100);
case 'string':
return input.toLowerCase();
case 'boolean':
return input ? 'Yes' : 'No';
default:
console.error('No provided type');
return '';
}
};
// [x] Wenn input eine number ist, gibst du die Zahl multipliziert mit 100 als string zurück.
// [x] Wenn input ein string ist, wird string in Kleinbuchstaben zurückgegeben.
// [x] 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.
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.
}

View File

@@ -0,0 +1,33 @@
(() => {
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 displayStatus = (status2) => {
if (status2) {
return `Status: ${status2}`;
} else {
return "No status avaible";
}
};
let status;
console.log(displayStatus("Active"));
console.log(displayStatus("Pending"));
console.log(displayStatus(null));
console.log(displayStatus(void 0));
console.log(displayStatus(status));
console.log(displayStatus(""));
}
}
});
require_main();
})();

View File

@@ -1,17 +1,31 @@
{
// Ü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:
const displayStatus = (status: string | null | undefined): string => {
if (status) {
return `Status: ${status}`;
} else {
return 'No status avaible';
}
};
// [x] Wenn status truthy ist, wird die Zeichenfolge "Status: ", verkettet mit Status.
// [x] Wenn status fehlerhaft ist, wird die Zeichenfolge "No status available." zurückgegeben.
// [x] Verwende die Truthiness Narrowing, um zu prüfen, ob der Status truthy oder falsch ist.
// [x] Kopiere den Code unten und füge ihn ein, um deine Implementierung zu testen.
// [x] Kopiere den Code unten und füge ihn ein, um deine Implementierung zu testen.
let status;
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(status)); // => "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.
// console.log(displayStatus()); // => Expected 1 arguments, but got 0.
}

View File

@@ -0,0 +1,52 @@
(() => {
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 analyzeInput = (input) => {
switch (typeof input) {
case "boolean":
return input ? "Input is exactly true" : "Input is exactly false";
case "number":
if (input === 0) {
return "Input is zero";
} else if (input > 0) {
return "Input is a positive number";
} else {
return "Input is a negative number";
}
case "string":
if (input === "hello") {
return `Input is the string '${input}'`;
} else {
return "Input is another string";
}
default:
return "Unknown input";
}
};
console.log("undefined", "object");
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();
})();

View File

@@ -1,7 +1,29 @@
const analyzeInput = (input: string | number | boolean): string => {
// Your code here
{
const analyzeInput = (input: string | number | boolean | undefined | null): string => {
switch (typeof input) {
case 'boolean':
return input ? 'Input is exactly true' : 'Input is exactly false';
case 'number':
if (input === 0) {
return 'Input is zero';
} else if (input > 0) {
return 'Input is a positive number';
} else {
return 'Input is a negative number';
}
case 'string':
if (input === 'hello') {
return `Input is the string '${input}'`;
} else {
return 'Input is another string';
}
default:
return 'Unknown input';
}
};
console.log(typeof undefined, typeof null);
console.log(analyzeInput(true)); // => "Input is exactly true"
console.log(analyzeInput(false)); // => "Input is exactly false"
console.log(analyzeInput(0)); // => "Input is zero"
@@ -16,20 +38,14 @@ 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.
// [x] "Input is exactly true" wenn input === true.
// [x] "Input is exactly false" wenn input === false.
// [x] "Input is zero" wenn input === 0.
// [x] "Input is a positive number" wenn input eine Zahl größer als null ist.
// [x] "Input is a negative number" wenn input eine Zahl kleiner als null ist.
// [x] "Input is the string 'hello'" wenn input === "hello".
// [x] "Input is another string" wenn input irgendein anderer String ist.
// [x] "Unknown input" andernfalls.
// Verwende Equality- und Vergleichsoperatoren, um den Typ und den Wert der Eingabe einzugrenzen.
}

View File

@@ -1,14 +1,26 @@
{
type Guitar = { strum: () => void };
type Piano = { pressKeys: () => void };
const play = (instrument: Guitar | Piano) => {
// Your code here
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!"
play(piano); // => "Pressing piano keys!"
}

View File

@@ -0,0 +1,31 @@
(() => {
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 handleValue = (value) => {
if (typeof value === "string") {
console.log(value.toUpperCase());
} else if (typeof value === "number") {
console.log(value * 2);
}
console.log(value ? "It's true!" : "It's false!");
};
handleValue("hello");
handleValue("TypeScript");
handleValue(21);
handleValue(50);
handleValue(false);
handleValue(true);
}
});
require_main();
})();

View File

@@ -1,11 +1,3 @@
// 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.
@@ -14,12 +6,27 @@ 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.
const handleValue = (value: string | number | boolean): void => {
// Wenn es eine string ist, protokolliere die Version in Großbuchstaben.
if (typeof value === 'string') {
console.log(value.toUpperCase());
// Wenn es sich um eine number handelt, logge ihren Wert multipliziert mit 2.
} else if (typeof value === 'number') {
console.log(value * 2);
// Wenn es eine boolean ist, protokolliere "It's true!" oder "It's false!". Verwende einen ternären Operator.
}
console.log(value ? "It's true!" : "It's false!");
};
// 2Teste die Funktion mit verschiedenen Eingaben.
// 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!"

View File

@@ -1,9 +1,3 @@
// 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.
@@ -13,15 +7,25 @@ console.log(handleInput(5)); // => 25
// 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.
const handleInput = (value: string | number | boolean | null): string | number => {
if (typeof value === 'number') {
return value * value;
// Wenn die input eine boolean ist, wird "True" oder "False" zurückgegeben.
} else if (typeof value === 'boolean') {
return value ? 'True' : 'False';
// Wenn input eine string ist, wird die Großbuchstabenversion der Zeichenkette zurückgegeben.
} else if (typeof value === 'string') {
return value.toUpperCase();
// Wenn input eine number ist, wird das Quadrat der Zahl zurückgegeben.
}
// Wenn die input null ist, gibst du "No value provided" zurück.
return 'No value provided';
};
// 3 Teste die Funktion mit verschiedenen Eingaben, um zu überprüfen, ob TypeScript die Typen korrekt eingrenzt.
console.log(handleInput(null)); // => "No value provided"
console.log(handleInput(true)); // => "True"
console.log(handleInput('hello')); // => "HELLO"
console.log(handleInput(5)); // => 25

View File

@@ -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,74 @@ 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;
};
// 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.
const isCar = (vehicle: Car | Truck): vehicle is Car => {
return Object.hasOwn(vehicle, 'drive');
return (vehicle as Car).drive !== undefined;
};
// 3 Implementiere eine Funktion handleVehicle, die einen Parameter vom Typ Car | Truck akzeptiert:
const handleVehicle = (vehicle: Car | Truck) => {
// Wenn das Fahrzeug ein Car ist, rufe drive() an.
if (isCar(vehicle)) {
vehicle.drive();
// Wenn das Fahrzeug ein Truck ist, rufe loadCargo() an.
} else {
vehicle.loadCargo();
}
};
// 4 Erstelle ein Array von Car | Truck Objekten und filtere nur die Autos mit dem isCar Predicate heraus.
const vehicles: (Car | Truck)[] = [
{
drive: () => {
console.log('Car driving');
},
},
{
loadCargo: () => {
console.log('Truck loading cargo!');
},
},
{
drive: () => {
console.log('Car driving');
},
},
{
drive: () => {
console.log('Car driving');
},
},
{
drive: () => {
console.log('Car driving');
},
},
];
// 5 Teste deine Funktionen mit verschiedenen Eingaben.
// Test the filtered array
// const cars = vehicles.filter(isCar);
const cars = vehicles.filter((vehicle) => {
return isCar(vehicle);
});
cars.forEach((car) => {
car.drive();
}); // => "Car driving"
console.log('Filter End');
// 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"

View File

@@ -1,7 +1,4 @@
// 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 +6,24 @@ 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 = (x: number, y: 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 = (func: MathOperation, a: number, b: number): number => {
return func(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: number, b: number): number => {
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
}

View File

@@ -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>

View File

@@ -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"
}

View File

@@ -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.

View File

@@ -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>

View File

@@ -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"
}

View File

@@ -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.

View File

@@ -0,0 +1,49 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Übung 22: Optionale Parameter implementieren</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 22: Optionale Parameter implementieren</h2>
<p>
Erstelle die Funktion <code>createUserProfile</code>, die drei
Parameter benötigt: einen obligatorischen username und zwei
optionale Parameter, <code>age</code> und <code>email</code>. Die
Funktion sollte einen String mit einer Profilzusammenfassung
zurückgeben. Wenn keine optionalen Parameter angegeben werden,
sollten die Standardwerte verwendet werden, um das Profil zu
vervollständigen.
</p>
<h4>Anweisungen:</h4>
<ul class="list">
<li>
Definiere eine Funktion <code>createUserProfile</code>, die
akzeptiert:
<ul class="list">
<li><code>username</code> (erforderlich, String)</li>
<li><code>age</code> (optional, Zahl, Standardwert ist 18)</li>
<li>
<code>email</code> (optional, String, Standardwert: "N/A")
</li>
</ul>
</li>
<li>
Die Funktion sollte einen String zurückgeben, der das Profil des
Nutzers zusammenfasst.
</li>
</ul>
</div>
</div>
</main>
</body>
</html>

View File

@@ -0,0 +1,13 @@
{
"name": "22_fn-optional-props",
"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"
}

View File

@@ -0,0 +1,19 @@
createUserProfile('JohnDoe', 25, 'john@example.com');
// => "User JohnDoe is 25 years old and can be contacted at john@example.com."
createUserProfile('JaneDoe');
// => "User JaneDoe is 18 years old and can be contacted at N/A."
// Übung 22: Optionale Parameter implementieren
// Erstelle die Funktion createUserProfile, die drei Parameter benötigt: einen obligatorischen username und zwei optionale Parameter, age und email. Die Funktion sollte einen String mit einer Profilzusammenfassung zurückgeben. Wenn keine optionalen Parameter angegeben werden, sollten die Standardwerte verwendet werden, um das Profil zu vervollständigen.
// Anweisungen:
// Definiere eine Funktion createUserProfile, die akzeptiert:
// username (erforderlich, String)
// age (optional, Zahl, Standardwert ist 18)
// email (optional, String, Standardwert: "N/A")
// Die Funktion sollte einen String zurückgeben, der das Profil des Nutzers zusammenfasst.

View File

@@ -0,0 +1,58 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Übung 23: Restparameter und Restargumente</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 23: Restparameter und Restargumente</h2>
<p>
Schreibe zwei Funktionen: eine, die Restparameter verwendet, um eine
unterschiedliche Anzahl von Zahlen zu akzeptieren und ihre Summe zu
berechnen, und eine andere, die die Spread-Syntax verwendet, um ein
Array von Zahlen in einzelne Argumente für eine mathematische
Funktion zu verteilen.
</p>
<h4>Anweisungen:</h4>
<ol class="list">
<li>
Definiere eine Funktion <code>sumAll</code>, die einen
Restparameter, bestehend aus einer variablen Anzahl von
numerischen Argumenten, annimmt und die Summe aller übergebenen
Zahlen zurückgibt. Verwende die Methode reduce, um die Summe des
Arrays zu berechnen.
</li>
<li>
Als Nächstes definierst du eine Funktion namens
<code>calculateHypotenuse</code>, die zwei Zahlen als Argumente
akzeptiert und die Hypotenuse mithilfe der Formel
<code>√(a² + b²)</code>
berechnet. Du solltest diese Funktion aufrufen, indem du ein Array
mit zwei Zahlen mit Hilfe der Spread-Syntax ausbreitest. (Tipp:
Verwende <code>Math.sqrt()</code>)
</li>
<li>
Teste schließlich die Funktion <code>sumAll</code>, indem du sie
mit mehreren Zahlen aufrufst und das Ergebnis protokollierst.
Teste die Funktion <code>calculateHypotenuse</code>, indem du ein
Array mit zwei Zahlen erstellst, dieses Array in die Funktion
überträgst und das Ergebnis protokollierst. Versuche außerdem,
<code>calculateHypotenuse</code> mit einem Array aufzurufen, das
nicht genau zwei Zahlen enthält, um das Type-Checking von
TypeScript zu beobachten.
</li>
</ol>
</div>
</div>
</main>
</body>
</html>

View File

@@ -0,0 +1,13 @@
{
"name": "23_fn-rest-params-args",
"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"
}

View File

@@ -0,0 +1,23 @@
// Example usage of sumAll
// Define total
console.log(total); // => 15
// Example usage of calculateHypotenuse with spread syntax
// Define hypotenuse
console.log(hypotenuse); // => 5
// Attempting to call calculateHypotenuse with incorrect number of arguments
const invalidSides = [3, 4, 5];
// Define invalidHypotenuse to call calculateHypotenuse with invalidSides => TypeScript Error: Expected 2 arguments, but got 3.
// Übung 23: Restparameter und Restargumente
// Schreibe zwei Funktionen: eine, die Restparameter verwendet, um eine unterschiedliche Anzahl von Zahlen zu akzeptieren und ihre Summe zu berechnen, und eine andere, die die Spread-Syntax verwendet, um ein Array von Zahlen in einzelne Argumente für eine mathematische Funktion zu verteilen.
// Anweisungen:
// 1 Definiere eine Funktion sumAll, die einen Restparameter, bestehend aus einer variablen Anzahl von numerischen Argumenten, annimmt und die Summe aller übergebenen Zahlen zurückgibt. Verwende die Methode reduce, um die Summe des Arrays zu berechnen.
// 2 Als Nächstes definierst du eine Funktion namens calculateHypotenuse, die zwei Zahlen als Argumente akzeptiert und die Hypotenuse mithilfe der Formel √(a² + b²) berechnet. Du solltest diese Funktion aufrufen, indem du ein Array mit zwei Zahlen mit Hilfe der Spread-Syntax ausbreitest. (Tipp: Verwende Math.sqrt())
// 3 Teste schließlich die Funktion sumAll, indem du sie mit mehreren Zahlen aufrufst und das Ergebnis protokollierst. Teste die Funktion calculateHypotenuse, indem du ein Array mit zwei Zahlen erstellst, dieses Array in die Funktion überträgst und das Ergebnis protokollierst. Versuche außerdem, calculateHypotenuse mit einem Array aufzurufen, das nicht genau zwei Zahlen enthält, um das Type-Checking von TypeScript zu beobachten.

View File

@@ -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 24: Parameter Destrukturierung</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 24: Parameter Destrukturierung</h2>
<p>
In dieser Übung übst du die Anwendung der Parameterdestrukturierung
in TypeScript, indem du zwei einfache Funktionen erstellst. Die
erste Funktion destrukturiert einen Objektparameter und verwendet
einen Standardwert für eine seiner Eigenschaften. Die zweite
Funktion destrukturiert einen Array-Parameter. Beide Funktionen
enthalten Type Annotations, um sicherzustellen, dass sie die
richtige Struktur erhalten.
</p>
<h4>Anweisungen:</h4>
<ol class="list">
<li>
Erstelle eine Funktion <code>displayUserInfo</code>, die die
Eigenschaften <code>name</code> und <code>age</code> aus einem
Objektparameter destrukturiert und einen Standardwert für
<code>age</code> liefert.
</li>
<li>
Erstelle eine Funktion <code>getFirstTwoElements</code>, die die
ersten beiden Elemente aus einem Array-Parameter zerstört.
</li>
<li>
Teste deine Funktionen, indem du sie mit den richtigen Argumenten
aufrufst.
</li>
</ol>
</div>
</div>
</main>
</body>
</html>

View File

@@ -0,0 +1,13 @@
{
"name": "24_fn-destructuring",
"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"
}

View File

@@ -0,0 +1,19 @@
// Example usage of displayUserInfo
displayUserInfo({ name: 'John' }); // => Hello, John! You are 25 years old.
displayUserInfo({ name: 'Alice', age: 30 }); // => Hello, Alice! You are 30 years old.
// Example usage of getFirstTwoElements
getFirstTwoElements([5, 10]); // => First: 5, Second: 10
getFirstTwoElements([8]); // => First: 8, Second: undefined
// Übung 24: Parameter Destrukturierung
// In dieser Übung übst du die Anwendung der Parameterdestrukturierung in TypeScript, indem du zwei einfache Funktionen erstellst. Die erste Funktion destrukturiert einen Objektparameter und verwendet einen Standardwert für eine seiner Eigenschaften. Die zweite Funktion destrukturiert einen Array-Parameter. Beide Funktionen enthalten Type Annotations, um sicherzustellen, dass sie die richtige Struktur erhalten.
// Anweisungen:
// 1 Erstelle eine Funktion displayUserInfo, die die Eigenschaften name und age aus einem Objektparameter destrukturiert und einen Standardwert für age liefert.
// 2 Erstelle eine Funktion getFirstTwoElements, die die ersten beiden Elemente aus einem Array-Parameter zerstört.
// 3 Teste deine Funktionen, indem du sie mit den richtigen Argumenten aufrufst.

View File

@@ -0,0 +1,68 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Übung 25: Optionale und readonly Eigenschaften</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 25: Optionale und readonly Eigenschaften</h2>
<p>
In dieser Übung erstellst du eine <code>interface</code> für ein
»Product«, die erforderliche, optionale und readonly Eigenschaften
enthält. Anschließend schreibst du eine Funktion, die Informationen
über das Produkt protokolliert und dabei optionale Eigenschaften
korrekt behandelt.
</p>
<h4>Anweisungen:</h4>
<ol class="list">
<li>
Definiere ein <code>Product</code> Interface, die Folgendes
beinhaltet:
<ul class="list">
<li>
Erforderliche Eigenschaften <code>id</code> (Number) und
<code>name</code> (String).
</li>
<li>
Optionale Eigenschaften <code>price</code> (Number) und
<code>description</code> (String).
</li>
<li>
Eine <code>readonly</code> <code>category</code> (String)
Eigenschaft.
</li>
</ul>
</li>
<li>
Schreibe eine Funktion <code>printProductDetails</code>, die ein
<code>Product</code> Objekt annimmt und:
<ul class="list">
<li>
Druckt die <code>name</code>, <code>category</code> und
<code>id</code>.
</li>
<li>
Wenn <code>price</code> <code>undefined</code> ist, drucke
"Price: Not available".
</li>
<li>
Wenn <code>description</code> <code>undefined</code> ist,
drucke "No description availabler".
</li>
</ul>
</li>
</ol>
</div>
</div>
</main>
</body>
</html>

View File

@@ -0,0 +1,13 @@
{
"name": "25_obj-read-only",
"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"
}

View File

@@ -0,0 +1,17 @@
// Übung 25: Optionale und readonly Eigenschaften
// In dieser Übung erstellst du eine interface für eine Product, die erforderliche, optionale und readonly Eigenschaften enthält. Anschließend schreibst du eine Funktion, die Informationen über das Produkt protokolliert und dabei optionale Eigenschaften korrekt behandelt.
// Anweisungen:
// 1 Definiere ein Product Interface, die Folgendes beinhaltet:
// Erforderliche Eigenschaften id (Number) und name (String).
// Optionale Eigenschaften price (Number) und description (String).
// Eine readonly category (String) Eigenschaft.
// 2 Schreibe eine Funktion printProductDetails, die ein Product Objekt annimmt und:
// Druckt die name, category und id.
// Wenn price undefined ist, drucke "Price: Not available".
// Wenn description undefined ist, drucke "No description availabler".

View File

@@ -0,0 +1,63 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Übung 26: Eine verschachtelte Objekteigenschaft aktualisieren</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 26: Eine verschachtelte Objekteigenschaft aktualisieren</h2>
<p>
In dieser Übung definierst du ein Interface mit readonly und
veränderbaren Eigenschaften und aktualisierst ein verschachteltes
Objekt innerhalb des Interfaces. Du übst den Umgang mit
verschachtelten Objekten und <code>readonly</code> Eigenschaften.
</p>
<h4>Anweisungen:</h4>
<ol class="list">
<li>
Erstelle ein <code>Employee</code> Interface, die Folgendes
enthält:
<ul class="list">
<li>
Eine <code>readonly</code> <code>employeeId</code> (Number)
Eigenschaft.
</li>
<li>
Eine veränderbare Detail-Eigenschaft, die ein Objekt ist, das
Folgendes enthält: <code>position</code> (String) und
<code>salary</code> (Number)
</li>
</ul>
</li>
<li>
Schreibe eine Funktion <code>updateEmployeePosition</code> die:
<ul class="list">
<li>
Akzeptiert ein <code>Employee</code> Objekt und einen neuen
<code>position</code> String.
</li>
<li>
Aktualisiert die <code>position</code> des Mitarbeiters,
verhindert aber jede Änderung der <code>employeeId</code>.
</li>
</ul>
</li>
<li>
Teste die Funktion, indem du ein Employee-Objekt erstellst und die
Position aktualisierst.
</li>
</ol>
</div>
</div>
</main>
</body>
</html>

View File

@@ -0,0 +1,13 @@
{
"name": "26_obj-update",
"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"
}

View File

@@ -0,0 +1,19 @@
// Übung 26: Eine verschachtelte Objekteigenschaft aktualisieren
// In dieser Übung definierst du ein Interface mit readonly und veränderbaren Eigenschaften und aktualisierst ein verschachteltes Objekt innerhalb des Interfaces. Du übst den Umgang mit verschachtelten Objekten und readonly Eigenschaften.
// Anweisungen:
// Erstelle ein Employee Interface, die Folgendes enthält:
// Eine readonly employeeId (Number) Eigenschaft.
// Eine veränderbare Detail-Eigenschaft, die ein Objekt ist, das Folgendes enthält: position (String), salary (Number)
// Schreibe eine Funktion updateEmployeePosition die:
// Akzeptiert ein Employee Objekt und einen neuen position String.
// Aktualisiert die position des Mitarbeiters, verhindert aber jede Änderung der employeeId.
// Teste die Funktion, indem du ein Employee-Objekt erstellst und die Position aktualisierst.

View File

@@ -0,0 +1,84 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>
Übung 27: Kombiniere Optional, Readonly und Required Properties in einem
Interface
</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 27: Kombiniere Optional, Readonly und Required Properties in
einem Interface
</h2>
<p>
In dieser Übung erstellst du ein <code>Car</code> Interface mit
required, optional und readonly Eigenschaften. Anschließend
schreibst du eine Funktion, um ein neues <code>Car</code> Objekt zu
erstellen und Änderungen an veränderbaren Eigenschaften zu
verarbeiten.
</p>
<h4>Anweisungen:</h4>
<ol class="list">
<li>
Definiere ein <code>Car</code> Interface, die Folgendes
beinhaltet:
<ul class="list">
<li>
Erforderliche Eigenschaften <code>make</code> (string) und
<code>model</code> (string).
</li>
<li>
Optionale Eigenschaften <code>year</code> (Number) und
<code>color</code> (String).
</li>
<li>
Eine readonly <code>vin</code> (string) Eigenschaft
(Fahrzeugidentifikationsnummer).
</li>
</ul>
</li>
<li>
Schreibe eine Funktion <code>createCar</code> die:
<ul class="list">
<li>
Nimmt <code>make</code>, <code>model</code> und
<code>vin</code> auf und gibt ein <code>Car</code> Objekt
zurück.
</li>
<li>
Optional können <code>year</code> und <code>color</code>
akzeptiert werden.
</li>
</ul>
</li>
<li>
Schreibe eine weitere Funktion <code>paintCar</code> die:
<ul class="list">
<li>
Akzeptiert ein <code>Car</code> Objekt und einen neuen
<code>color</code> String.
</li>
<li>
Aktualisiert die <code>color</code> des Fahrzeugs (falls
vorhanden), verhindert aber jede Änderung an der
<code>vin</code>.
</li>
</ul>
</li>
</ol>
</div>
</div>
</main>
</body>
</html>

View File

@@ -0,0 +1,13 @@
{
"name": "27_obj-interface-props",
"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"
}

View File

@@ -0,0 +1,25 @@
// Übung 27: Kombiniere Optional, Readonly und Required Properties in einem Interface
// In dieser Übung erstellst du ein Car Interface mit required, optional und readonly Eigenschaften. Anschließend schreibst du eine Funktion, um ein neues Car Objekt zu erstellen und Änderungen an veränderbaren Eigenschaften zu verarbeiten.
// Anweisungen:
// 1 Definiere ein Car Interface, die Folgendes beinhaltet:
// Erforderliche Eigenschaften make (string) und model (string).
// Optionale Eigenschaften year (Number) und color (String).
// Eine readonly vin (string) Eigenschaft (Fahrzeugidentifikationsnummer).
// 2 Schreibe eine Funktion createCar die:
// Nimmt make, model und vin auf und gibt ein Car Objekt zurück.
// Optional können year und color akzeptiert werden.
// 3 Schreibe eine weitere Funktion paintCar die:
// Akzeptiert ein Car Objekt und einen neuen color String.
// Aktualisiert die color des Fahrzeugs (falls vorhanden), verhindert aber jede Änderung an der vin.

View File

@@ -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 28: Excess Property Checks mit Object Literals</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 28: Excess Property Checks mit Object Literals</h2>
<p>
In dieser Übung definierst du ein Interface <code>Car</code> und
schreibst eine Funktion, die ein Objekt vom Typ
<code>Car</code> annimmt. Du wirst untersuchen, wie TypeScript
Excess Property Checks erzwingt, indem es versucht, ein Objekt mit
zusätzlichen Eigenschaften an die Funktion zu übergeben.
</p>
<h4>Anweisungen:</h4>
<ol class="list">
<li>
Definiere ein <code>Car</code> Interface mit den folgenden
Eigenschaften:
<ul class="list">
<li><code>make</code>: String</li>
<li><code>model</code>: String</li>
<li><code>year</code>: Number</li>
</ul>
</li>
<li>
Schreibe eine Funktion <code>printCarDetails</code>, die ein
Objekt vom Typ <code>Car</code> annimmt und die Details des Autos
ausgibt (<code>make</code>, <code>model</code> und
<code>year</code>).
</li>
<li>
Versuche, der Funktion ein Objekt zu übergeben, das eine
zusätzliche Eigenschaft hat, z. B. <code>color</code>. Beobachte,
wie TypeScript mit der überzähligen Eigenschaft umgeht und
erkläre, warum der Fehler auftritt.
</li>
</ol>
</div>
</div>
</main>
</body>
</html>

View File

@@ -0,0 +1,13 @@
{
"name": "28_obj-excess-prop-check",
"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"
}

View File

@@ -0,0 +1,15 @@
// Übung 28: Excess Property Checks mit Object Literals
// In dieser Übung definierst du ein Interface Car und schreibst eine Funktion, die ein Objekt vom Typ Car annimmt. Du wirst untersuchen, wie TypeScript Excess Property Checks erzwingt, indem es versucht, ein Objekt mit zusätzlichen Eigenschaften an die Funktion zu übergeben.
// Anweisungen:
// 1 Definiere ein Car Interface mit den folgenden Eigenschaften:
// - make: String
// - model: String
// - year: Number
// 2 Schreibe eine Funktion printCarDetails, die ein Objekt vom Typ Car annimmt und die Details des Autos ausgibt (make, model und year).
// 3 Versuche, der Funktion ein Objekt zu übergeben, das eine zusätzliche Eigenschaft hat, z. B. color. Beobachte, wie TypeScript mit der überzähligen Eigenschaft umgeht und erkläre, warum der Fehler auftritt.

View File

@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Übung 29: Extending einer einzelnen Interface</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 29: Extending einer einzelnen Interface</h2>
<p>
In dieser Übung wirst du eine bestehende
<code>Product</code> Interface erweitern, um einen spezifischeren
Typ <code>Electronics</code> zu erstellen. Du wirst zusätzliche
Eigenschaften für Elektronikprodukte definieren und ein Objekt des
Typs <code>Electronics</code>
erstellen.
</p>
<h4>Anweisungen:</h4>
<ol class="list">
<li>
Definiere ein <code>Product</code> Interface mit den Eigenschaften
<code>id</code>, <code>name</code> und <code>price</code>.
</li>
<li>
Erweitere die <code>Product</code> Interface um eine
<code>Electronics</code> Interface und füge die Eigenschaften
<code>brand</code> und <code>warranty</code> hinzu.
</li>
<li>Erstelle ein Objekt vom Typ <code>Electronics</code>.</li>
</ol>
</div>
</div>
</main>
</body>
</html>

View File

@@ -0,0 +1,13 @@
{
"name": "29_obj-extending-interface",
"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"
}

View File

@@ -0,0 +1,11 @@
// Übung 29: Extending einer einzelnen Interface
// In dieser Übung wirst du eine bestehende Product Interface erweitern, um einen spezifischeren Typ Electronics zu erstellen. Du wirst zusätzliche Eigenschaften für Elektronikprodukte definieren und ein Objekt des Typs Electronics erstellen.
// Anweisungen:
// 1 Definiere ein Product Interface mit den Eigenschaften id, name und price.
// 2 Erweitere die Product Interface um eine Electronics Interface und füge die Eigenschaften brand und warranty hinzu.
// 3 Erstelle ein Objekt vom Typ Electronics.

View File

@@ -0,0 +1,47 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>
Übung 30: Einzigartige Eigenschaften zu einem Subtyp hinzufügen
</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 30: Einzigartige Eigenschaften zu einem Subtyp hinzufügen
</h2>
<p>
In dieser Übung wirst du die <code>Product</code> Interface
erweitern, um einen Typ <code>Furniture</code> zu erstellen, der
spezielle Eigenschaften für Möbel hinzufügt, wie
<code>material</code> und <code>dimensions</code>.
</p>
<h4>Anweisungen:</h4>
<ol class="list">
<li>
Erweitere die <code>Product</code> Interface, um eine
<code>Furniture</code> Interface zu erstellen.
</li>
<li>
Füge die Eigenschaften <code>material</code> und
<code>dimensions</code> zu den Möbeln hinzu.
</li>
<li>
Erstelle ein Objekt vom Typ Furniture, das ein Möbelstück
darstellt.
</li>
</ol>
</div>
</div>
</main>
</body>
</html>

View File

@@ -0,0 +1,13 @@
{
"name": "30_obj-subtyp",
"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"
}

View File

@@ -0,0 +1,11 @@
// Übung 30: Einzigartige Eigenschaften zu einem Subtyp hinzufügen
// In dieser Übung wirst du die Product Interface erweitern, um einen Typ Furniture zu erstellen, der spezielle Eigenschaften für Möbel hinzufügt, wie material und dimensions.
// Anweisungen:
// 1 Erweitere die Product Interface, um eine Furniture Interface zu erstellen.
// 2 Füge die Eigenschaften material und dimensions zu den Möbeln hinzu.
// 3 Erstelle ein Objekt vom Typ Furniture, das ein Möbelstück darstellt.

View File

@@ -0,0 +1,42 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Übung 31: Generic Functions für Arrays</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 31: Generic Functions für Arrays</h2>
<p>
In dieser Übung erstellst du eine generische Funktion, die mit
Arrays beliebigen Typs funktioniert. Du definierst eine Funktion,
die das erste Element des Arrays zurückgibt und es TypeScript
ermöglicht, den Elementtyp aus dem übergebenen Array abzuleiten.
</p>
<h4>Anweisungen:</h4>
<ol class="list">
<li>
Definiere eine generische Funktion
<code>getFirstElement</code>, die ein Array beliebigen Typs
annimmt und das erste Element oder undefined zurückgibt, wenn das
Array leer ist.
</li>
<li>
Rufe die Funktion mit Arrays verschiedener Typen auf
(<code>number[]</code>, <code>string[]</code>, etc.) und
protokolliere das Ergebnis.
</li>
</ol>
</div>
</div>
</main>
</body>
</html>

View File

@@ -0,0 +1,13 @@
{
"name": "31_obj-generics-fns",
"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"
}

View File

@@ -0,0 +1,9 @@
// Übung 31: Generic Functions für Arrays
// In dieser Übung erstellst du eine generische Funktion, die mit Arrays beliebigen Typs funktioniert. Du definierst eine Funktion, die das erste Element des Arrays zurückgibt und es TypeScript ermöglicht, den Elementtyp aus dem übergebenen Array abzuleiten.
// Anweisungen:
// 1 Definiere eine generische Funktion getFirstElement, die ein Array beliebigen Typs annimmt und das erste Element oder undefined zurückgibt, wenn das Array leer ist.
// 2 Rufe die Funktion mit Arrays verschiedener Typen auf (number[], string[], etc.) und protokolliere das Ergebnis.

Binary file not shown.

View File

@@ -43,6 +43,8 @@
return data;
} catch (err: unknown) {
if (err instanceof Error) {
console.log(err.message);
console.error(err);
throw err; // paranoid
}

View File

@@ -97,5 +97,6 @@
evaluateScore2(Rating.One); // OK
evaluateScore2(Rating.Five); // OK
evaluateScore2(Rating.Four); // OK
evaluateScore2(5); // OK
// evaluateScore2(Rating.Six);
}

View File

@@ -2,9 +2,9 @@
{
const displayValue = (value: string | number): void => {
if (typeof value === 'string') {
console.log(value.toUpperCase());
// Type Guard: typeof value === "string"
// Narrowing: 'value' is now of type 'string'
console.log(value.toUpperCase());
} else {
// Narrowing: 'value' is now of type 'number'
console.log(value.toFixed(2));

View File

@@ -8,6 +8,7 @@ Der In Operator wird verwendet, um zu bestimmen, ob ein Objekt ein bestimmtes Pr
type Car = { drive: () => void };
type Boat = { sail: () => void };
// type predicate : vehicle is Car
const isCar = (vehicle: Car | Boat): vehicle is Car => {
return Object.hasOwn(vehicle, 'drive');
};

View File

@@ -25,6 +25,7 @@ Type Narrowing wird verwendet, um den Typ einer Variablen zu beschränken, wenn
if (typeof value === 'string') {
return `String: ${value}`; // early return bei Narrowing
}
return `Number: ${value.toFixed(2)}`;
};
@@ -40,7 +41,6 @@ Type Narrowing wird verwendet, um den Typ einer Variablen zu beschränken, wenn
if (typeof input === 'string') {
return `String input: ${input.toUpperCase()}`;
}
return `Number input: ${input.toFixed(2)}`;
};

View File

@@ -13,6 +13,7 @@ WICHTIG: "Außerdem grenzt es den Typ der Variablen auf der Grundlage des Ergebn
const isFish = (pet: Fish | Bird): pet is Fish => {
//return 'swim' in pet; // in Operator führt Type- Narrowing durch.
return Object.hasOwn(pet, 'swim');
// return pet.hasOwnProperty('swim');
// return (pet as Fish).swim !== undefined;
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 333 KiB

View File

@@ -0,0 +1,45 @@
(() => {
// src/01_fn-type-expression.ts
{
let printToConsole = function(s) {
console.log(s);
}, mathOperation = function(fn) {
return fn(10, 20);
};
const mathOperationFn = (fn) => {
return fn(4, 5);
};
const multiply = (a, b) => {
return a * b;
};
const multiply2 = (a, b) => {
return a * b;
};
console.log(multiply2(2, 4));
mathOperationFn(multiply);
const greeter = (fn) => {
fn("Hello, World");
};
const greeter2 = (fn) => {
fn("Hello, World");
};
greeter(printToConsole);
greeter2(printToConsole);
const logMessage = (message) => {
console.log(message);
};
const logMessage2 = (message) => {
console.log(message);
};
const logMessage3 = (message) => {
console.log(message);
};
logMessage("Hello");
logMessage2("Hola");
logMessage3("Hallo");
const subtract = (x, y) => {
return x - y;
};
console.log(mathOperation(subtract));
}
})();

View File

@@ -0,0 +1,29 @@
(() => {
// src/02_fn-call-signature.ts
{
let doSomething = function(fn) {
console.log(fn.description + " returned " + fn(6));
};
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 add = (x, y) => {
return x + y;
};
const multiply = (x, y) => {
return x * y;
};
console.log(add(123, 321));
console.log(multiply(25, 25));
const myFunc = (someArg) => {
return someArg > 3;
};
myFunc.description = "Default description";
doSomething(myFunc);
}
})();

View File

@@ -0,0 +1,34 @@
(() => {
// 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 resultBoolean = identity(true);
console.log(resultNumber, resultString, resultBoolean);
const firstElement = (arr) => {
return arr[0];
};
console.log(firstElement(["Adel", "Andreas", "Ersin", "Kahleel"]));
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);
}
})();

View File

@@ -0,0 +1,53 @@
(() => {
// src/04_fn-optional-parameter.ts
{
const greet = (name) => {
if (name) {
return `Hello, ${name}!`;
} else {
return "Hello!";
}
};
console.log(greet());
console.log(greet("Alice"));
}
{
const greet = (name = "Guest") => {
return `Hello, ${name}!`;
};
console.log(greet());
console.log(greet("Alice"));
}
{
const sendMessage = (message, recipient) => {
if (recipient) {
return `Message: "${message}" sent to ${recipient}`;
} else {
return `Message: "${message}" sent to default recipient`;
}
};
console.log(sendMessage("Welcome", "John"));
console.log(sendMessage("Welcome"));
}
{
const formatNumber = (num, decimals) => {
if (decimals !== void 0) {
return num.toFixed(decimals);
} else {
return num.toString();
}
};
console.log(formatNumber(3.14159, 2));
console.log(formatNumber(3.14159));
}
{
const processItems = (items, callback) => {
for (let i = 0; i < items.length; i++) {
callback(items[i], i);
}
};
processItems(["apple", "banana", "cherry"], (item) => {
console.log(item);
});
}
})();

View File

@@ -0,0 +1,27 @@
(() => {
// src/05_fn-rest-parameter.ts
{
const multiply = (n, ...m) => {
return m.map((x) => n * x);
};
const a = multiply(10, 1, 2, 3, 4);
console.log(a);
console.log(multiply(10));
console.log(multiply(2, 2, 3));
const greetNames = (greeting, ...names) => {
return names.map((name) => {
return `${greeting} ${name}`;
});
};
console.log(greetNames("Hello", "John").join("\n"));
console.log(greetNames("Hi", "John", "Tick", "Trick", "Track").join("\n"));
const concatenate = (...strings) => {
return strings.join(" ");
};
const concatenate2 = (...strings) => {
return strings.join(" ");
};
concatenate("Ich", "bin", "ein", "Text");
concatenate2("Ich", "bin", "ein", "Text");
}
})();

View File

@@ -0,0 +1,36 @@
(() => {
// src/06_fn-destructuring.ts
{
let printCoordinates = function([x, y]) {
console.log(`X: ${x}, Y: ${y}`);
};
const greetUser = (user) => {
console.log(`Hello, ${user.name}! You are ${user.age} years old.`);
};
const greetUser2 = ({ name, age }) => {
console.log(`Hello, ${name}! You are ${age} years old.`);
};
const greetUser3 = ({
name,
age
} = { name: "John", age: 18 }) => {
console.log(`Hello, ${name}! You are ${age} years old.`);
};
greetUser3({ name: "Alice", age: 25 });
const greetUser4 = (user) => {
const { name, age } = user;
console.log(`Hello, ${name}! You are ${age} years old.`);
};
greetUser4({ name: "Alice", age: 25 });
const sum = ({ a, b, c }) => {
console.log(a + b + c);
};
const sum2 = (sumObj) => {
const { a, b, c } = sumObj;
console.log(a + b + c);
};
sum({ a: 10, b: 5, c: 15 });
sum2({ a: 10, b: 5, c: 15 });
printCoordinates([10, 20]);
}
})();

View File

@@ -0,0 +1,76 @@
(() => {
// src/07_never-void-unknown.ts
{
let infiniteLoop = function() {
while (true) {
console.log("This loop will never end");
}
};
const logMessage = (message) => {
console.log(message);
};
const logMessage2 = (message) => {
console.log(message);
return "message";
};
logMessage("Hello, TypeScript!");
console.log(logMessage2("Hello, TypeScript!"));
const clearScreen = () => {
};
clearScreen();
const processInput = (input) => {
if (typeof input === "string") {
console.log(`The input is a string: ${input.toUpperCase()}`);
} else if (typeof input === "number") {
console.log(`The input is a number: ${input + 10}`);
} else {
console.log("Unknown type of input");
}
};
processInput("Hello");
processInput(42);
processInput(true);
const getPersonAsync = async () => {
try {
const res = await fetch("https://dummyjson.com/users/1?select=firstName,lastName,age");
if (!res.ok) {
throw Error(`HTTP-Request went wrong: ${res.status}`);
}
const data = await res.json();
return data;
} catch (err) {
if (err instanceof Error) {
console.log(err.message);
console.error(err);
throw err;
}
throw new Error("An unknown error occurred.");
}
};
getPersonAsync().then((data) => console.log(data));
const safeParse = (s) => {
return JSON.parse(s);
};
const result = safeParse('{"name": "Alice"}');
if (typeof result === "object" && result !== null && "name" in result) {
console.log(result.name);
}
const throwError = (message) => {
throw new Error(message);
};
throwError("Something went wrong!");
const handleShape = (shape) => {
switch (shape) {
case "circle":
return "Handling a circle";
case "square":
return "Handling a square";
default:
const _exhaustiveCheck = shape;
return _exhaustiveCheck;
}
};
console.log(handleShape("circle"));
console.log(handleShape("square"));
}
})();

View File

@@ -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>TypeScript - Functions</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> -->
<!-- <script src="assets/js/03_fn-generics.js" defer></script> -->
<!-- <script src="assets/js/04_fn-optional-parameter.js" defer></script> -->
<!-- <script src="assets/js/05_fn-rest-parameter.js" defer></script> -->
<!-- <script src="assets/js/06_fn-destructuring.js" defer></script> -->
<script src="assets/js/07_never-void-unknown.js" defer></script>
</head>
<body>
<main>
<div class="container py-5">
<h1>TypeScript - Functions</h1>
<p>
TypeScript ist eine von Microsoft entwickelte Skriptsprache, die auf den Vorschlägen zum
ECMAScript-6-Standardbasiert 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/Understand-Typescript.jpg" alt="TypeScript Kreisdiagramm" class="img-thumbnail" />
</div>
</main>
</body>
</html>

View File

@@ -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.1"
}
},
"node_modules/@esbuild/aix-ppc64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz",
"integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"aix"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/android-arm": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz",
"integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/android-arm64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz",
"integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/android-x64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz",
"integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/darwin-arm64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz",
"integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/darwin-x64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz",
"integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/freebsd-arm64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz",
"integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/freebsd-x64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz",
"integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-arm": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz",
"integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-arm64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz",
"integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-ia32": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz",
"integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-loong64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz",
"integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==",
"cpu": [
"loong64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-mips64el": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz",
"integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==",
"cpu": [
"mips64el"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-ppc64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz",
"integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-riscv64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz",
"integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==",
"cpu": [
"riscv64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-s390x": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz",
"integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==",
"cpu": [
"s390x"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-x64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz",
"integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/netbsd-arm64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz",
"integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/netbsd-x64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz",
"integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openbsd-arm64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz",
"integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openbsd-x64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz",
"integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openharmony-arm64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz",
"integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openharmony"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/sunos-x64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz",
"integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"sunos"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-arm64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz",
"integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-ia32": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz",
"integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-x64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz",
"integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/esbuild": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz",
"integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"bin": {
"esbuild": "bin/esbuild"
},
"engines": {
"node": ">=18"
},
"optionalDependencies": {
"@esbuild/aix-ppc64": "0.28.1",
"@esbuild/android-arm": "0.28.1",
"@esbuild/android-arm64": "0.28.1",
"@esbuild/android-x64": "0.28.1",
"@esbuild/darwin-arm64": "0.28.1",
"@esbuild/darwin-x64": "0.28.1",
"@esbuild/freebsd-arm64": "0.28.1",
"@esbuild/freebsd-x64": "0.28.1",
"@esbuild/linux-arm": "0.28.1",
"@esbuild/linux-arm64": "0.28.1",
"@esbuild/linux-ia32": "0.28.1",
"@esbuild/linux-loong64": "0.28.1",
"@esbuild/linux-mips64el": "0.28.1",
"@esbuild/linux-ppc64": "0.28.1",
"@esbuild/linux-riscv64": "0.28.1",
"@esbuild/linux-s390x": "0.28.1",
"@esbuild/linux-x64": "0.28.1",
"@esbuild/netbsd-arm64": "0.28.1",
"@esbuild/netbsd-x64": "0.28.1",
"@esbuild/openbsd-arm64": "0.28.1",
"@esbuild/openbsd-x64": "0.28.1",
"@esbuild/openharmony-arm64": "0.28.1",
"@esbuild/sunos-x64": "0.28.1",
"@esbuild/win32-arm64": "0.28.1",
"@esbuild/win32-ia32": "0.28.1",
"@esbuild/win32-x64": "0.28.1"
}
}
}
}

View File

@@ -0,0 +1,14 @@
{
"name": "01_ts-types",
"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.1"
}
}

View File

@@ -0,0 +1,79 @@
// 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; // Funktionstype-deklaration
const mathOperationFn = (fn: MathFn): number => {
return fn(4, 5);
};
const multiply = (a: number, b: number): number => {
return a * b;
};
const multiply2: MathFn = (a, b) => {
return a * b;
};
console.log(multiply2(2, 4)); // => 8
mathOperationFn(multiply); // => 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"
// ------
const logMessage = (message: string): void => {
console.log(message);
};
const logMessage2: (param: string) => void = (message) => {
console.log(message);
};
type LogFn = (param: string) => void;
// RECOMMENDED
const logMessage3: LogFn = (message) => {
console.log(message);
};
logMessage('Hello');
logMessage2('Hola');
logMessage3('Hallo');
// -----
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
}

View File

@@ -0,0 +1,60 @@
// 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 = (a: number, b: 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 sum2:(a: number, b: number) => string = (a:number, b:number):string => {
// return `The sum is ${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
//--------
// 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) {
console.log(fn.description + ' returned ' + fn(6));
}
const myFunc = (someArg: number): boolean => {
return someArg > 3;
};
myFunc.description = 'Default description';
doSomething(myFunc); // => "Default description returned true"
}

View File

@@ -0,0 +1,57 @@
// 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 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 resultBoolean = identity<boolean>(true); // T is boolean
console.log(resultNumber, resultString, resultBoolean);
// ---------------
// const firstElement = (arr: any[]) => {
// return arr[0];
// };
const firstElement = <T>(arr: T[]): T | undefined => {
return arr[0];
};
console.log(firstElement<string>(['Adel', 'Andreas', 'Ersin', 'Kahleel'])); // => 'Adel' <- 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);
}

View File

@@ -0,0 +1,64 @@
// Optionale Parameter
/*
In TypeScript sind Funktionen unglaublich flexibel und du kannst sowohl erforderliche als auch optionale Parameter definieren.
*/
{
const greet = (name?: string): string => {
if (name) {
return `Hello, ${name}!`;
} else {
return 'Hello!';
}
};
console.log(greet()); // => "Hello, Guest!"
console.log(greet('Alice')); // => "Hello, Alice!"
}
{
// Default Parameter
const greet = (name: string = 'Guest'): string => {
return `Hello, ${name}!`;
};
console.log(greet()); // => "Hello, Guest!"
console.log(greet('Alice')); // => "Hello, Alice!"
}
{
const sendMessage = (message: string, recipient?: string): string => {
if (recipient) {
return `Message: "${message}" sent to ${recipient}`;
} else {
return `Message: "${message}" sent to default recipient`;
}
};
console.log(sendMessage('Welcome', 'John')); // => 'Message: "Welcome" sent to John'
console.log(sendMessage('Welcome')); // => 'Message: "Welcome" sent to default recipient'
}
{
const formatNumber = (num: number, decimals?: number): string => {
if (decimals !== undefined) {
return num.toFixed(decimals);
} else {
return num.toString();
}
};
console.log(formatNumber(3.14159, 2)); // => '3.14'
console.log(formatNumber(3.14159)); // => '3.14159'
}
// Optionale Parameter in Callbacks
{
const processItems = (items: string[], callback: (item: string, index?: number) => void) => {
for (let i = 0; i < items.length; i++) {
callback(items[i], i);
}
};
processItems(['apple', 'banana', 'cherry'], (item) => {
console.log(item);
});
}

View File

@@ -0,0 +1,39 @@
// Rest Parameter und Argumente
/*
In TypeScript kannst du mit Restparametern Funktionen erstellen, die eine beliebige Anzahl von Argumenten annehmen können.
*/
{
const multiply = (n: number, ...m: number[]): number[] => {
return m.map((x) => n * x);
};
// 'a' gets the value [10, 20, 30, 40]
const a = multiply(10, 1, 2, 3, 4);
console.log(a); // => [10, 20, 30, 40]
console.log(multiply(10)); // => []
console.log(multiply(2, 2, 3)); // => [4,6]
// ------
const greetNames = (greeting: string, ...names: string[]): string[] => {
return names.map((name) => {
return `${greeting} ${name}`;
});
};
console.log(greetNames('Hello', 'John').join('\n'));
console.log(greetNames('Hi', 'John', 'Tick', 'Trick', 'Track').join('\n'));
// -------
const concatenate = (...strings: string[]): string => {
return strings.join(' ');
};
const concatenate2 = (...strings: Array<string>): string => {
return strings.join(' ');
};
concatenate('Ich', 'bin', 'ein', 'Text');
concatenate2('Ich', 'bin', 'ein', 'Text');
}

View File

@@ -0,0 +1,63 @@
// Parameter-Destrukturierung
/*
Destrukturierung vereinfacht deinen Code, indem du Werte direkt aus Objekten oder Arrays auspacken und sie Variablen innerhalb der Funktionsparameter zuweisen kannst.
*/
{
const greetUser = (user: { name: string; age: number }) => {
console.log(`Hello, ${user.name}! You are ${user.age} years old.`);
};
const greetUser2 = ({ name, age }: { name: string; age: number }) => {
console.log(`Hello, ${name}! You are ${age} years old.`);
};
const greetUser3: (o: { name: string; age: number }) => void = (
{
name,
age,
}: {
name: string;
age: number;
} = { name: 'John', age: 18 },
): void => {
console.log(`Hello, ${name}! You are ${age} years old.`);
};
greetUser3({ name: 'Alice', age: 25 });
// ------
// RECOMMENDED
type GreetUserFn = (user: { name: string; age: number }) => void;
const greetUser4: GreetUserFn = (user) => {
const { name, age } = user;
console.log(`Hello, ${name}! You are ${age} years old.`);
};
greetUser4({ name: 'Alice', age: 25 });
// -----
const sum = ({ a, b, c }: { a: number; b: number; c: number }): void => {
console.log(a + b + c);
};
// RECOMMENDED
type SumObject = { a: number; b: number; c: number };
const sum2 = (sumObj: SumObject): void => {
const { a, b, c } = sumObj;
console.log(a + b + c);
};
sum({ a: 10, b: 5, c: 15 }); // => 30
sum2({ a: 10, b: 5, c: 15 }); // => 30
// -------
function printCoordinates([x, y]: [number, number]) {
console.log(`X: ${x}, Y: ${y}`);
}
printCoordinates([10, 20]); // => X: 10, Y: 20
}

View File

@@ -0,0 +1,127 @@
// Types: never, unknown, void
/*
In TypeScript gibt es drei spezielle Typen: never, unknown und void. Diese Typen werden in bestimmten Situationen verwendet, um bestimmte Verhaltensweisen zu modellieren.
*/
// - void wird für Funktionen verwendet, die keinen Wert zurückgeben, was bedeutet, dass die Funktion eine Aktion ausführt, ohne ein Ergebnis zu liefern. Es wird kein Ergebnis erwartet, dennoch können Ergebnisse zurückgegeben werden ohne Fehlermeldung
// - unknown ist eine sicherere Alternative zu any und erfordert Type-Checking, bevor Operationen mit Werten unbekannten Typs durchgeführt werden, wodurch Laufzeitfehler vermieden werden.
// - never repräsentiert Funktionen, die niemals zurückkehren, entweder durch das Werfen von Fehlern oder durch unendliches Ausführen, und ist nützlich für die Durchsetzung von exhaustive Type-Checking.
{
//
type LogFn = (a: string) => void;
const logMessage = (message: string): void => {
console.log(message);
};
const logMessage2: LogFn = (message) => {
console.log(message);
return 'message';
};
logMessage('Hello, TypeScript!');
console.log(logMessage2('Hello, TypeScript!'));
const clearScreen = (): void => {
// document.body.innerHTML = '';
};
clearScreen();
// -------
const processInput = (input: unknown): void => {
if (typeof input === 'string') {
console.log(`The input is a string: ${input.toUpperCase()}`);
} else if (typeof input === 'number') {
console.log(`The input is a number: ${input + 10}`);
} else {
console.log('Unknown type of input');
}
};
processInput('Hello');
processInput(42);
processInput(true);
// ------
interface Userdata {
id?: number;
firstName: string;
lastName: string;
age: number;
}
// unkown Example
const getPersonAsync = async (): Promise<Userdata> => {
try {
const res: Response = await fetch('https://dummyjson.com/users/1?select=firstName,lastName,age');
if (!res.ok) {
throw Error(`HTTP-Request went wrong: ${res.status}`);
}
const data: Userdata = await res.json();
return data;
} catch (err: unknown) {
if (err instanceof Error) {
console.log(err.message);
console.error(err);
throw err; // paranoid
}
throw new Error('An unknown error occurred.');
}
};
getPersonAsync().then((data) => console.log(data));
// ----
// unknown als Rückgabewert erfordert type checking vor Verwendung
const safeParse = (s: string): unknown => {
return JSON.parse(s);
};
const result = safeParse('{"name": "Alice"}');
// console.log(result.name); // 'result' is of type 'unknown'.
// TypeScript requires you to check the type before using `result`
if (typeof result === 'object' && result !== null && 'name' in result) {
console.log(result.name); // Safe access after type check
}
// ----
const throwError = (message: string): never => {
throw new Error(message);
};
throwError('Something went wrong!');
function infiniteLoop(): never {
while (true) {
console.log('This loop will never end');
}
}
//------
type Shape = 'circle' | 'square';
const handleShape = (shape: Shape): string => {
switch (shape) {
case 'circle':
return 'Handling a circle';
case 'square':
return 'Handling a square';
default:
// throw new Error("shape doesn't exist");
const _exhaustiveCheck: never = shape; // TypeScript error if a new shape is added
return _exhaustiveCheck;
}
};
console.log(handleShape('circle'));
console.log(handleShape('square'));
// console.log(handleShape('triangle'));
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 333 KiB

View File

@@ -0,0 +1,46 @@
(() => {
// src/01_obj-props.ts
{
let person = {
name: "Alice",
age: 30
};
let person2 = {
name: "Alice",
age: 30
};
console.table(person);
console.table(person2);
const book1 = { title: "The Great Gatsby" };
const book2 = { title: "1984", author: "George Orwell" };
const book3 = {
title: "Moby Dick",
author: "Herman Melville",
pages: 635
};
console.log(book1);
console.log(book2);
console.log(book3);
const printBookInfo = (book) => {
const author = book.author ?? "Unknown";
const pages = book.pages ?? "Page count not available";
console.log(`Title: ${book.title}, Author: ${author}, Pages: ${pages}`);
};
const printBookInfoWithDefaults = ({ title, author = "Unknown", pages = 1 }) => {
console.log(`Title: ${title}, Author: ${author}, Pages: ${pages}`);
};
printBookInfoWithDefaults({ title: "To Kill a Mockingbird" });
printBookInfo(book3);
printBookInfo(book2);
}
{
const person = { firstName: "John", lastName: "Doe", age: 30 };
person.age = 31;
const employee = {
id: 101,
details: { position: "Developer", salary: 5e4 }
};
employee.details.salary = 55e3;
const config = { apiKey: "abc123", timeout: 5e3 };
}
})();

View File

@@ -0,0 +1,12 @@
(() => {
// src/02_excess-property-checks.ts
{
const myCar = { make: "Toyota", model: "Camry", year: 2020 };
console.log(myCar);
const printCarDetails = (car) => {
const { make, model, year } = car;
console.log(`Car Make: ${car.make}, Model: ${car.model}, Year: ${car.year}`);
};
printCarDetails({ make: "Tesla", model: "Model 3", year: 2021 });
}
})();

View File

@@ -0,0 +1,29 @@
(() => {
// src/03_obj-extends.ts
{
const laptop = {
id: 1,
name: "Gaming Laptop",
price: 1500,
brand: "TechBrand",
warranty: 24
};
const chair = {
id: 2,
name: "Office Chair",
price: 200,
material: "Leather",
dimensions: { length: 60, width: 50, height: 110 }
};
const tshirt = {
id: 2,
name: "T-Shirt",
price: 20,
size: "M",
color: "Red"
};
console.log(laptop);
console.log(chair);
console.log(tshirt);
}
})();

View File

@@ -0,0 +1,76 @@
(() => {
// src/04_obj-more-types.ts
{
const numbers = [10, 20, 30, 40];
const numbers2 = [10, 20, 30, 40];
const namesAndAges = ["John", 123, "Trick", 32];
const namesAndAges2 = ["John", 123, "Trick", 32];
const strings = ["eins", "zwei", "drei"];
const strings2 = ["eins", "zwei", "drei"];
console.log(numbers, numbers2, namesAndAges, namesAndAges2, strings, strings2);
}
{
const getFirstElement = (arr) => {
return arr.length > 0 ? arr[0] : void 0;
};
const firstNumber = getFirstElement([1, 2, 3]);
const firstString = getFirstElement(["apple", "banana", "cherry"]);
console.log(firstNumber);
console.log(firstString);
console.log(getFirstElement([]));
}
{
let pair = ["hello", 42];
console.log(pair[0]);
console.log(pair[1]);
}
{
let Direction;
((Direction2) => {
Direction2["Up"] = "up";
Direction2["Down"] = "down";
Direction2["Left"] = "left";
Direction2["Right"] = "right";
})(Direction || (Direction = {}));
let currentDirection = "up" /* Up */;
console.log(currentDirection);
currentDirection = "down" /* Down */;
console.log(currentDirection);
let Status;
((Status2) => {
Status2["PENDING"] = "pending";
Status2["SUCCESS"] = "success";
Status2["ERROR"] = "error";
})(Status || (Status = {}));
const status = "success" /* SUCCESS */;
console.log(status);
}
{
let Richtung;
((Richtung2) => {
Richtung2[Richtung2["Norden"] = 2] = "Norden";
Richtung2[Richtung2["Osten"] = 3] = "Osten";
Richtung2[Richtung2["Sueden"] = 4] = "Sueden";
Richtung2[Richtung2["Westen"] = 5] = "Westen";
})(Richtung || (Richtung = {}));
console.log(2 /* Norden */);
console.log(3 /* Osten */);
}
{
const numbers = {
one: 1,
two: 2,
three: 3
};
console.log(numbers);
}
{
const symbol1 = /* @__PURE__ */ Symbol("key");
const symbol2 = /* @__PURE__ */ Symbol("key");
const obj = {
[symbol1]: "value1",
[symbol2]: "value2"
};
console.log(obj);
}
})();

View File

@@ -0,0 +1,26 @@
<!doctype html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>TypeScript - Objects</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
<!-- <script src="assets/js/01_obj-props.js" defer></script> -->
<!-- <script src="assets/js/02_excess-property-checks.js" defer></script> -->
<!-- <script src="assets/js/03_obj-extends.js" defer></script> -->
<script src="assets/js/04_obj-more-types.js" defer></script>
</head>
<body>
<main>
<div class="container py-5">
<h1>TypeScript - Objects</h1>
<p>
TypeScript ist eine von Microsoft entwickelte Skriptsprache, die auf den Vorschlägen zum
ECMAScript-6-Standardbasiert 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/Understand-Typescript.jpg" alt="TypeScript Kreisdiagramm" class="img-thumbnail" />
</div>
</main>
</body>
</html>

View File

@@ -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.1"
}
},
"node_modules/@esbuild/aix-ppc64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz",
"integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"aix"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/android-arm": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz",
"integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/android-arm64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz",
"integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/android-x64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz",
"integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/darwin-arm64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz",
"integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/darwin-x64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz",
"integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/freebsd-arm64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz",
"integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/freebsd-x64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz",
"integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-arm": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz",
"integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-arm64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz",
"integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-ia32": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz",
"integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-loong64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz",
"integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==",
"cpu": [
"loong64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-mips64el": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz",
"integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==",
"cpu": [
"mips64el"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-ppc64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz",
"integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-riscv64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz",
"integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==",
"cpu": [
"riscv64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-s390x": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz",
"integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==",
"cpu": [
"s390x"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-x64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz",
"integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/netbsd-arm64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz",
"integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/netbsd-x64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz",
"integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openbsd-arm64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz",
"integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openbsd-x64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz",
"integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openharmony-arm64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz",
"integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openharmony"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/sunos-x64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz",
"integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"sunos"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-arm64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz",
"integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-ia32": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz",
"integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-x64": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz",
"integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/esbuild": {
"version": "0.28.1",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz",
"integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"bin": {
"esbuild": "bin/esbuild"
},
"engines": {
"node": ">=18"
},
"optionalDependencies": {
"@esbuild/aix-ppc64": "0.28.1",
"@esbuild/android-arm": "0.28.1",
"@esbuild/android-arm64": "0.28.1",
"@esbuild/android-x64": "0.28.1",
"@esbuild/darwin-arm64": "0.28.1",
"@esbuild/darwin-x64": "0.28.1",
"@esbuild/freebsd-arm64": "0.28.1",
"@esbuild/freebsd-x64": "0.28.1",
"@esbuild/linux-arm": "0.28.1",
"@esbuild/linux-arm64": "0.28.1",
"@esbuild/linux-ia32": "0.28.1",
"@esbuild/linux-loong64": "0.28.1",
"@esbuild/linux-mips64el": "0.28.1",
"@esbuild/linux-ppc64": "0.28.1",
"@esbuild/linux-riscv64": "0.28.1",
"@esbuild/linux-s390x": "0.28.1",
"@esbuild/linux-x64": "0.28.1",
"@esbuild/netbsd-arm64": "0.28.1",
"@esbuild/netbsd-x64": "0.28.1",
"@esbuild/openbsd-arm64": "0.28.1",
"@esbuild/openbsd-x64": "0.28.1",
"@esbuild/openharmony-arm64": "0.28.1",
"@esbuild/sunos-x64": "0.28.1",
"@esbuild/win32-arm64": "0.28.1",
"@esbuild/win32-ia32": "0.28.1",
"@esbuild/win32-x64": "0.28.1"
}
}
}
}

View File

@@ -0,0 +1,14 @@
{
"name": "01_ts-types",
"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.1"
}
}

View File

@@ -0,0 +1,114 @@
// Property Modifiers
/*
In TypeScript kannst du die Modifizierer für Eigenschaften in Objekten verwenden, um die Zugriffsrechte und Verhaltensweisen zu steuern.
*/
{
let person: { name: string; age: number } = {
name: 'Alice',
age: 30,
};
type Person = {
name: string;
age: number;
};
let person2: Person = {
name: 'Alice',
age: 30,
};
// person.lastName // Property 'lastName' does not exist on type '{ name: string; age: number; }'.
console.table(person);
console.table(person2);
// ------------------------------------------------------------
// type Book = {
interface Book {
title: string;
author?: string;
pages?: number;
}
const book1: Book = { title: 'The Great Gatsby' }; // Valid: no author or pages
const book2: Book = { title: '1984', author: 'George Orwell' }; // Valid: no pages
const book3: Book = {
title: 'Moby Dick',
author: 'Herman Melville',
pages: 635,
}; // Valid
console.log(book1);
console.log(book2);
console.log(book3);
// ------------------------------
// ?? operator => nullish coalescing
const printBookInfo = (book: Book) => {
const author = book.author ?? 'Unknown'; // Use "Unknown" if author is undefined
const pages = book.pages ?? 'Page count not available';
console.log(`Title: ${book.title}, Author: ${author}, Pages: ${pages}`);
};
// destructuring with defaults
const printBookInfoWithDefaults = ({ title, author = 'Unknown', pages = 1 }: Book) => {
console.log(`Title: ${title}, Author: ${author}, Pages: ${pages}`);
};
printBookInfoWithDefaults({ title: 'To Kill a Mockingbird' });
// => Title: To Kill a Mockingbird, Author: Unknown, Pages: 1
printBookInfo(book3);
// => Title: Moby Dick, Author: Herman Melville, Pages: 635
printBookInfo(book2);
// => Title: 1984, Author: George Orwell, Pages: Page count not available
}
// ----------------------
// Readonly Properties
{
interface Person {
readonly firstName: string;
readonly lastName: string;
age: number;
}
const person: Person = { firstName: 'John', lastName: 'Doe', age: 30 };
person.age = 31; // This works: age can be updated
// The following lines will cause TypeScript errors
// person.firstName = "Jane"; // Error: Cannot assign to 'firstName' because it is a read-only property
// person.lastName = "Smith"; // Error: Cannot assign to 'lastName' because it is a read-only property
interface Employee {
readonly id: number;
details: {
position: string;
salary: number;
};
}
const employee: Employee = {
id: 101,
details: { position: 'Developer', salary: 50000 },
};
employee.details.salary = 55000; // This works: you can modify the 'details' object
// The following will cause an error
// employee.id = 102; // Error: Cannot assign to 'id' because it is a read-only property
interface Config {
readonly apiKey?: string;
readonly timeout?: number;
}
const config: Config = { apiKey: 'abc123', timeout: 5000 };
// export default config; // außerhalb von codeblöcken
// The following will cause errors because both properties are readonly
// config.apiKey = "newKey"; // Error: Cannot assign to 'apiKey' because it is a read-only property
// config.timeout = 3000; // Error: Cannot assign to 'timeout' because it is a read-only property
}

View File

@@ -0,0 +1,29 @@
// Excess Property Checks
/*
Wenn du ein Objekt in TypeScript definierst, musst du sicherstellen, dass das Objekt genau der erwarteten Struktur entspricht. TypeScript prüft nicht nur, ob alle erforderlichen Eigenschaften vorhanden sind, sondern auch, dass keine zusätzlichen, unbeabsichtigten Eigenschaften enthalten sind. Diese Funktion wird als "Excess Property Checks" bezeichnet.
*/
{
// type Car = {
interface Car {
make: string;
model: string;
year: number;
}
const myCar: Car = { make: 'Toyota', model: 'Camry', year: 2020 };
// const myCar2: Car = { make: "Honda", model: "Accord", year: 2022, color: "blue" };
// => TypeScript error: Object literal may only specify known properties, and 'color' does not exist in type 'Car'.
console.log(myCar);
const printCarDetails = (car: Car) => {
const { make, model, year } = car;
console.log(`Car Make: ${car.make}, Model: ${car.model}, Year: ${car.year}`);
};
printCarDetails({ make: 'Tesla', model: 'Model 3', year: 2021 });
// printCarDetails({ make: "Tesla", model: "Model 3", year: 2021, color: "black" });
// => TypeScript error: Object literal may only specify known properties, and 'color' does not exist in type 'Car'.
}

View File

@@ -0,0 +1,57 @@
// Extending Types
/*
In TypeScript kannst du bestehende Typen erweitern, um speziellere Versionen von ihnen zu erstellen. Mit diesem Ansatz kannst du bestehende Typstrukturen wiederverwenden und erweitern, ohne Code zu duplizieren.
*/
{
interface Product {
readonly id: number;
name: string;
price: number;
}
interface Electronics extends Product {
brand: string;
warranty: number; // warranty in months
}
interface Furniture extends Product {
material: string;
dimensions: { length: number; width: number; height: number };
}
interface Clothing extends Product {
size: string;
color: string;
}
const laptop: Electronics = {
id: 1,
name: 'Gaming Laptop',
price: 1500,
brand: 'TechBrand',
warranty: 24,
};
const chair: Furniture = {
id: 2,
name: 'Office Chair',
price: 200,
material: 'Leather',
dimensions: { length: 60, width: 50, height: 110 },
};
// chair.id = 3; // readonly Cannot assign to 'id' because it is a read-only property.
const tshirt: Clothing = {
id: 2,
name: 'T-Shirt',
price: 20,
size: 'M',
color: 'Red',
};
console.log(laptop); // => { id: 1, name: 'Gaming Laptop', price: 1500, brand: 'TechBrand', warranty: 24 }
console.log(chair); // => { id: 2, name: 'Office Chair', price: 200, material: 'Leather', dimensions: { length: 60, width: 50, height: 110 } }
console.log(tshirt); // => { id: 2, name: 'T-Shirt', price: 20, size: 'M', color: 'Red' }
}

View File

@@ -0,0 +1,107 @@
// Object (special) Types
// Der Array-Typ
{
const numbers: Array<number> = [10, 20, 30, 40];
const numbers2: number[] = [10, 20, 30, 40];
const namesAndAges: Array<number | string> = ['John', 123, 'Trick', 32];
const namesAndAges2: (number | string)[] = ['John', 123, 'Trick', 32];
const strings: Array<string> = ['eins', 'zwei', 'drei'];
const strings2: string[] = ['eins', 'zwei', 'drei'];
console.log(numbers, numbers2, namesAndAges, namesAndAges2, strings, strings2);
}
// generische Funktionen
{
const getFirstElement = <T>(arr: Array<T>): T | undefined => {
return arr.length > 0 ? arr[0] : undefined;
};
const firstNumber = getFirstElement([1, 2, 3]); // TypeScript infers T as number
const firstString = getFirstElement(['apple', 'banana', 'cherry']); // TypeScript infers T as string
console.log(firstNumber); // => 1
console.log(firstString); // => "apple"
console.log(getFirstElement([])); // => undefined
}
// tuple Type
{
type StringNumberPair = [string, number];
let pair: StringNumberPair = ['hello', 42];
console.log(pair[0]); // => "hello"
console.log(pair[1]); // => 42
}
// enum Type
{
enum Direction {
Up = 'up',
Down = 'down',
Left = 'left',
Right = 'right',
}
let currentDirection = Direction.Up;
console.log(currentDirection); // => 'up'
currentDirection = Direction.Down;
console.log(currentDirection); // => 'down'
enum Status {
PENDING = 'pending',
SUCCESS = 'success',
ERROR = 'error',
}
const status = Status.SUCCESS;
console.log(status); // => 'success'
}
{
enum Richtung {
Norden = 2,
Osten,
Sueden,
Westen,
}
console.log(Richtung.Norden); //=> 2
console.log(Richtung.Osten); //=> 3
}
// Record Type
{
type StringNumberMap = Record<string, number>;
const numbers: StringNumberMap = {
one: 1,
two: 2,
three: 3,
};
console.log(numbers); // => { one: 1, two: 2, three: 3 }
}
// Symbol Type
{
const symbol1: symbol = Symbol('key');
const symbol2: symbol = Symbol('key');
// console.log(symbol1 === symbol2); // => false => because they are different symbols
const obj = {
[symbol1]: 'value1',
[symbol2]: 'value2',
};
console.log(obj); // => { [Symbol(key)]: 'value1', [Symbol(key)]: 'value2' }
}