This commit is contained in:
Philippe Torrel
2026-10-20 13:17:52 +02:00
parent 490de9179b
commit 9f316103e9
46 changed files with 1872 additions and 3 deletions
@@ -18,7 +18,7 @@ type NumberFn = (value: number) => number;
// halve: Teilt die eingegebene Zahl durch 2.
// Der Parametertyp wird jeweils aus NumberOperation abgeleitet.
const double: NumberOperation = (value) => value * 2;
const double: NumberOperation = value => value * 2; // prettier-ignore
const halve: NumberOperation = (value) => value / 2;
const double2: NumberFn = (value) => value * 2;
@@ -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>
@@ -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"
}
@@ -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.
@@ -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>
@@ -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"
}
@@ -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.
@@ -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>
@@ -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"
}
@@ -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.
@@ -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>
@@ -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"
}
@@ -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".
@@ -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>
@@ -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"
}
@@ -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.
@@ -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>
@@ -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"
}
@@ -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.
@@ -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>
@@ -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"
}
@@ -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.
@@ -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>
@@ -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"
}
@@ -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.
@@ -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>
@@ -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"
}
@@ -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.
@@ -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>
@@ -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"
}
@@ -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.
@@ -1,5 +1,5 @@
{
"name": "02_ts-functions",
"name": "ts-functions",
"version": "1.0.0",
"description": "",
"main": "index.js",
@@ -92,7 +92,7 @@ In TypeScript gibt es drei spezielle Typen: never, unknown und void. Diese Typen
}
// ----
// never
const throwError = (message: string): never => {
throw new Error(message);
};
Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

@@ -0,0 +1,47 @@
(() => {
// src/01_obj-props-readonly.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 author2 = book.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 };
}
})();
@@ -0,0 +1,12 @@
(() => {
// src/02_excess-property-check.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 });
}
})();
@@ -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);
}
})();
@@ -0,0 +1,79 @@
(() => {
// src/04_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 = {
true: 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);
}
})();
@@ -0,0 +1,27 @@
<!doctype html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>TypeScript - Grundlagen</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
<!-- <script src="assets/js/01_fn-type-expression.js" defer></script> -->
<!-- <script src="assets/js/02_fn-call-signature.js" defer></script> -->
<!-- <script src="assets/js/03_fn-destructuring.js" defer></script> -->
<script src="assets/js/04_never-void-unknown.js" defer></script>
</head>
<body>
<main>
<div class="container py-5">
<h1>TypeScript - Grundlagen</h1>
<p>
TypeScript ist eine von Microsoft entwickelte Skriptsprache, die auf den Vorschlägen zum ECMAScript-6-Standard
basiert und statische Typisierung zu JavaScript hinzufügt. Sprachkonstrukte von TypeScript, wie Klassen,
Vererbung, Module und anonyme Funktionen, wurden auch in ECMAScript 6 übernommen.
</p>
<img src="assets/img/what-is-ts.webp" alt="TypeScript Kreisdiagramm" class="img-thumbnail" />
</div>
</main>
</body>
</html>
@@ -0,0 +1,499 @@
{
"name": "02_ts-functions",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "02_ts-functions",
"version": "1.0.0",
"devDependencies": {
"esbuild": "^0.28.2"
}
},
"node_modules/@esbuild/aix-ppc64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz",
"integrity": "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"aix"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/android-arm": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.2.tgz",
"integrity": "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/android-arm64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz",
"integrity": "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/android-x64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.2.tgz",
"integrity": "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/darwin-arm64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz",
"integrity": "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/darwin-x64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz",
"integrity": "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/freebsd-arm64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz",
"integrity": "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/freebsd-x64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz",
"integrity": "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-arm": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz",
"integrity": "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-arm64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz",
"integrity": "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-ia32": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz",
"integrity": "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-loong64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz",
"integrity": "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==",
"cpu": [
"loong64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-mips64el": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz",
"integrity": "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==",
"cpu": [
"mips64el"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-ppc64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz",
"integrity": "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-riscv64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz",
"integrity": "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==",
"cpu": [
"riscv64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-s390x": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz",
"integrity": "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==",
"cpu": [
"s390x"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-x64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz",
"integrity": "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/netbsd-arm64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz",
"integrity": "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/netbsd-x64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz",
"integrity": "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openbsd-arm64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz",
"integrity": "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openbsd-x64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz",
"integrity": "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openharmony-arm64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz",
"integrity": "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openharmony"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/sunos-x64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz",
"integrity": "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"sunos"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-arm64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz",
"integrity": "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-ia32": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz",
"integrity": "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-x64": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz",
"integrity": "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/esbuild": {
"version": "0.28.2",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz",
"integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"bin": {
"esbuild": "bin/esbuild"
},
"engines": {
"node": ">=18"
},
"optionalDependencies": {
"@esbuild/aix-ppc64": "0.28.2",
"@esbuild/android-arm": "0.28.2",
"@esbuild/android-arm64": "0.28.2",
"@esbuild/android-x64": "0.28.2",
"@esbuild/darwin-arm64": "0.28.2",
"@esbuild/darwin-x64": "0.28.2",
"@esbuild/freebsd-arm64": "0.28.2",
"@esbuild/freebsd-x64": "0.28.2",
"@esbuild/linux-arm": "0.28.2",
"@esbuild/linux-arm64": "0.28.2",
"@esbuild/linux-ia32": "0.28.2",
"@esbuild/linux-loong64": "0.28.2",
"@esbuild/linux-mips64el": "0.28.2",
"@esbuild/linux-ppc64": "0.28.2",
"@esbuild/linux-riscv64": "0.28.2",
"@esbuild/linux-s390x": "0.28.2",
"@esbuild/linux-x64": "0.28.2",
"@esbuild/netbsd-arm64": "0.28.2",
"@esbuild/netbsd-x64": "0.28.2",
"@esbuild/openbsd-arm64": "0.28.2",
"@esbuild/openbsd-x64": "0.28.2",
"@esbuild/openharmony-arm64": "0.28.2",
"@esbuild/sunos-x64": "0.28.2",
"@esbuild/win32-arm64": "0.28.2",
"@esbuild/win32-ia32": "0.28.2",
"@esbuild/win32-x64": "0.28.2"
}
}
}
}
@@ -0,0 +1,14 @@
{
"name": "ts-objects",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"ts": "npx esbuild \"src/*.ts\" --watch --bundle --outdir=\"assets/js\" --loader:.ts=ts"
},
"keywords": [],
"type": "module",
"devDependencies": {
"esbuild": "^0.28.2"
}
}
@@ -0,0 +1,116 @@
// 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,
};
// RECOMMENDATION - use type or interface for object annotations
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; // optional operator (?)
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 (2021)
const printBookInfo = (book: Book) => {
const author = book.author ?? 'Unknown'; // Use "Unknown" if author is undefined
const author2 = book.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
}
@@ -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'.
}
@@ -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' }
}
@@ -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 = {
true: 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' }
}