This commit is contained in:
Philippe Torrel
2026-07-27 14:49:42 +02:00
parent 5590783348
commit a3f7493bd0
40 changed files with 1269 additions and 0 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,18 @@
(() => {
var __getOwnPropNames = Object.getOwnPropertyNames;
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
// src/main.ts
var require_main = __commonJS({
"src/main.ts"() {
function calculateDiscount(price, discount) {
return Number((price - discount).toFixed(2));
}
var finalPrice = calculateDiscount(100, 10);
console.log(`The final price is $${finalPrice}`);
}
});
require_main();
})();

View File

@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Übung 1: Erkennung von Typenfehlern</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" />
<script src="assets/js/bundle.js" defer></script>
</head>
<body>
<main>
<div class="container py-5">
<div class="alert alert-primary">
<h1>Übung 1: Erkennung von Typenfehlern</h1>
<p>
In dieser Übung übst du, Type Mismatches in TypeScript-Funktionen zu erkennen und aufzulösen. Dir wird eine
Funktion vorgelegt, die falsche Type Annotations hat. Deine Aufgabe ist es, die Probleme zu erkennen und die
Funktion so zu korrigieren, dass sie dem beabsichtigten Verhalten entspricht.
</p>
</div>
</div>
</main>
</body>
</html>

View File

@@ -0,0 +1,13 @@
{
"name": "01_erkennung-typenfehlern",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "01_erkennung-typenfehlern",
"version": "1.0.0",
"license": "ISC"
}
}
}

View File

@@ -0,0 +1,13 @@
{
"name": "01_erkennung-typenfehlern",
"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,5 @@
function calculateDiscount(price: number, discount: string): number {
return price - parseFloat(discount);
}
const finalPrice = calculateDiscount(100, 10);

View File

@@ -0,0 +1,18 @@
(() => {
var __getOwnPropNames = Object.getOwnPropertyNames;
var __commonJS = (cb, mod) => function __require() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
// src/main.ts
var require_main = __commonJS({
"src/main.ts"() {
var user = {
name: "John Doe",
age: 30
};
console.log(user.email?.toLowerCase());
}
});
require_main();
})();

View File

@@ -0,0 +1,34 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Übung 2: User E-Mail</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">
<h1>Übung 2: User E-Mail</h1>
<p>
In dieser Übung arbeitest du mit einem Objekt und stellst sicher, dass alle notwendigen Eigenschaften
vorhanden sind, bevor du auf sie zugreifst. Du nutzt Static Type-Checking von TypeScript, um undefinierte
Fehler beim Zugriff auf Objekteigenschaften zu vermeiden.
</p>
<ul class="list">
<li>
Ändere den Code, um einen Typ (<code>Interface</code>) einzuführen, der eine optionale E-Mail-Eigenschaft
enthält.
</li>
<li>
Verwende eine bedingte Anweisung für das Vorhandensein der E-Mail-Eigenschaft, bevor du versuchst, auf sie
zuzugreifen.
</li>
</ul>
</div>
</div>
</main>
</body>
</html>

View File

@@ -0,0 +1,13 @@
{
"name": "02_user-email",
"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,6 @@
const user = {
name: 'John Doe',
age: 30,
};
console.log(user.email.toLowerCase());

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 3: Vehicle 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">
<h1>Übung 3: Vehicle Interface</h1>
<p>
In dieser Übung arbeitest du mit einem Interface Vehicle und einem Objekt myCar, um sicherzustellen, dass
beide mit den richtigen Methodensignaturen übereinstimmen. In Fällen, in denen Interface und Objekt nicht
übereinstimmen, musst du Anpassungen vornehmen.
</p>
<h4>Aufgaben:</h4>
<ol class="list">
<li>
Identifiziere alle Unstimmigkeiten zwischen dem Interface <code>Vehicle</code> und dem Objekt
<code>myCar</code>.
</li>
<li>
Ändere das Interface <code>Vehicle</code>, das Objekt <code>myCar</code> oder beides, damit sie richtig
übereinstimmen.
</li>
<li>
Stelle sicher, dass die Funktion <code>operateVehicle</code> beide Methoden fehlerfrei aufrufen kann und
dass sie den Fahrzeugstatus korrekt zurückgibt.
</li>
</ol>
<h4>Anweisungen:</h4>
<ul class="list">
<li>
Das Interface Vehicle umfasst zwei Methoden:
<ul class="list">
<li>
<code>startEngine</code>: Akzeptiert einen String-Parameter für den Schlüssel und gibt einen
booleschen Wert zurück, der angibt, ob der Motor erfolgreich gestartet wurde.
</li>
<li>
<code>drive</code>: Akzeptiert einen Zahlenparameter für die Geschwindigkeit und gibt einen String
zurück, der den Fahrstatus beschreibt.
</li>
</ul>
</li>
<li>
Das Objekt <code>myCar</code> sollte beide Methoden korrekt implementieren, um das Interface Vehicle zu
entsprechen.
</li>
<li>
Ändere entweder das Interface <code>Vehicle</code> oder das Objekt <code>myCar</code> so, dass sie
übereinstimmen.
</li>
<p>
Stelle sicher, dass <code>operateVehicle</code> den Status des Fahrzeugs zurückgibt, nachdem du versucht
hast, den Motor zu starten und zu fahren.
</p>
</ul>
</div>
</div>
</main>
</body>
</html>

View File

@@ -0,0 +1,13 @@
{
"name": "03_vehicle-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,24 @@
interface Vehicle {
startEngine: (key: string) => boolean;
drive: (speed: number) => string;
}
const myCar = {
startEngine: () => {
console.log('Engine started');
return true;
},
drive: () => {
return 'Driving at default speed';
},
};
function operateVehicle(vehicle: Vehicle): string {
if (vehicle.startEngine('car-key')) {
return vehicle.drive(60);
} else {
return 'Engine failed to start.';
}
}
console.log(operateVehicle(myCar));

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 333 KiB

View File

@@ -0,0 +1,21 @@
(() => {
// src/01_interface-user.ts
var userOne = {
name: "John",
id: 1,
// username: 'JD', // Object literal may only specify known properties, and 'username' does not exist in type 'User'.
lastName: "Doe"
};
userOne.id = 2;
userOne.lastName = "Wick";
var userTwo = {
name: "Jane",
lastName: "Doe",
id: 3
};
Object.freeze(userTwo);
if (Object.hasOwn(userTwo, "name") && Object.hasOwn(userTwo, "id") && Object.hasOwn(userTwo, "lastName") && typeof userTwo.name === "string" && typeof userTwo.id === "number" && typeof userTwo.lastName === "string") {
console.log(userTwo);
console.log("Nerdy, without TS");
}
})();

View File

@@ -0,0 +1,19 @@
(() => {
// src/02_unions.ts
var value;
var value2;
value = 123;
value = "einszweidrei";
value2 = 123;
value2 = "einszweidrei";
function getResults() {
return Math.random() > 0.5 ? "success" : 404;
}
var getResults2 = () => {
return Math.random() > 0.5 ? "success" : "error";
};
console.log("John Wick".indexOf("o"));
console.log("John Wick".indexOf("XXX"));
console.log(getResults());
console.log(getResults2());
})();

View File

@@ -0,0 +1,24 @@
(() => {
// src/03_generics.ts
{
let identity = function(value) {
return value;
};
const identity2 = (value) => {
return value;
};
let stringResult = identity("Hello");
let numberResult = identity2(42);
console.log(stringResult, numberResult);
let names = ["Tick", "Trick", "Track"];
let names2 = ["Tick", "Trick", "Track"];
let lottoNumbers = [12, 4, 16, 45, 23, 19];
let lottoNumbers2 = [12, 4, 16, 45, 23, 19];
let lottoNumbers3 = [12, 4, 16, 45, 23, 19];
console.log(names, names2, lottoNumbers, lottoNumbers2, lottoNumbers3);
let namesWithAges = ["Bob", 23, "Alice", 44];
let namesWithAges2 = ["Bob", 23, "Alice", 44];
console.log("namesWithAges:", namesWithAges);
console.log("namesWithAges2:", namesWithAges2);
}
})();

View File

@@ -0,0 +1,13 @@
(() => {
// src/04_static-type-checking.ts
{
const data = [1, 2, 3, 4, 5, 6];
console.log(data.length);
const liEls = document.querySelectorAll("li");
liEls?.forEach((el) => {
el.addEventListener("click", (e) => {
console.log("click");
});
});
}
})();

View File

@@ -0,0 +1,11 @@
(() => {
// src/05_type-definition-function.ts
{
let calculateTotal = function(cart) {
return cart.getTotal();
};
const calculateTotal2 = (cart) => {
return cart.getTotal();
};
}
})();

View File

@@ -0,0 +1,25 @@
(() => {
// src/06_optional-exception.ts
{
const vehicle = {
make: "Toyota",
model: "Corolla",
startEngine() {
return `${this.make}: engine startet`;
}
};
const vehicle2 = {
make: "Jeep",
model: "Renegade",
startEngine() {
return `${this.make}: engine startet`;
},
stopEngine() {
console.log(`${this.make}: engine stoppt`);
}
};
console.log(vehicle.startEngine());
vehicle.stopEngine?.();
vehicle2.stopEngine?.();
}
})();

View File

@@ -0,0 +1,22 @@
(() => {
// src/07_static-type-check2.ts
{
const calculateArea = (radius, pi) => {
return radius ** 2 * parseFloat(pi);
};
console.log(calculateArea(10, "3.14"));
const greetUser = (name) => {
const greeting = "Hello, " + name;
const timestamp = /* @__PURE__ */ new Date();
console.log(greeting);
};
greetUser("John Wick");
const dayOfWeek = (/* @__PURE__ */ new Date()).getDay();
let message = "";
if (dayOfWeek === 0 || dayOfWeek === 6) {
message = "It's a weekend!";
} else if (dayOfWeek === 2) {
message = "It's Tuesday!";
}
}
})();

View File

@@ -0,0 +1,18 @@
(() => {
// src/08_explicit-type-annotaions.ts
{
let age = 23;
let message = "Welcome Text";
let toggle = true;
const logWelcome = (employee, hireDate) => {
console.log(`Welcome ${employee}, your hire date is ${hireDate.toDateString()}!`);
};
logWelcome("John Wick", /* @__PURE__ */ new Date("2024"));
const processEmployee = (employee) => {
console.log(
`${employee.name} started on ${employee.startDate.toDateString()} with a salary of $${employee.salary}.`
);
};
processEmployee({ name: "John", startDate: /* @__PURE__ */ new Date("2026-07-20"), salary: 5e4 });
}
})();

View File

@@ -0,0 +1,23 @@
(() => {
// src/09_type-inference.ts
{
let greeting = "Hello World";
let count = 123;
let isCompleted = true;
const isSmoking = true;
const houseNumber = 33;
let age = 40;
let names = ["Andreas", "Kahleel", "Ersin", "Adel"];
let namesInUpperCase = names.map((name) => {
return name.toUpperCase();
});
console.log(namesInUpperCase.join(", "));
let currentMessageNumber;
let randomValue;
let randomNumber;
randomNumber = "hello";
randomNumber = 123;
randomNumber = true;
randomNumber = () => "test";
}
})();

View File

@@ -0,0 +1,30 @@
<!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_interface-user.js" defer></script> -->
<!-- <script src="assets/js/02_unions.js" defer></script> -->
<!-- <script src="assets/js/03_generics.js" defer></script> -->
<!-- <script src="assets/js/04_static-type-checking.js" defer></script> -->
<!-- <script src="assets/js/05_type-definition-function.js" defer></script> -->
<!-- <script src="assets/js/06_optional-exception.js" defer></script> -->
<!-- <script src="assets/js/07_static-type-check2.js" defer></script> -->
<script src="assets/js/08_explicit-type-annotaions.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-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-fundamentals",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "01_ts-fundamentals",
"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-fundamentals",
"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,43 @@
interface User {
name: string;
lastName: string;
id: number;
}
const userOne: User = {
name: 'John',
id: 1,
// username: 'JD', // Object literal may only specify known properties, and 'username' does not exist in type 'User'.
lastName: 'Doe',
};
userOne.id = 2;
userOne.lastName = 'Wick';
// userOne._id = 2; // Property '_id' does not exist on type 'User'.
// userOne.lastname = 'Wick'; // Property 'lastname' does not exist on type 'User'.
// ==== OHNE TypeScript
const userTwo = {
name: 'Jane',
lastName: 'Doe',
id: 3,
};
Object.freeze(userTwo);
// userTwo.username = 'JD'
if (
Object.hasOwn(userTwo, 'name') &&
Object.hasOwn(userTwo, 'id') &&
Object.hasOwn(userTwo, 'lastName') &&
typeof userTwo.name === 'string' &&
typeof userTwo.id === 'number' &&
typeof userTwo.lastName === 'string'
) {
console.log(userTwo);
console.log('Nerdy, without TS');
}
// userTwo.hasOwnProperty('name');

View File

@@ -0,0 +1,29 @@
// Unions - Ein Union Type ermöglicht es dir, eine Variable zu deklarieren, die mehr als einen Werttyp enthalten kann.
// Type Annotation
let text: string = 'Ich bin ein Text';
type StringOrNumber = string | number; // unions
let value: string | number; // unions
let value2: StringOrNumber;
value = 123;
value = 'einszweidrei';
value2 = 123;
value2 = 'einszweidrei';
function getResults(): string | number {
return Math.random() > 0.5 ? 'success' : 404;
}
const getResults2 = (): string => {
return Math.random() > 0.5 ? 'success' : 'error';
};
console.log('John Wick'.indexOf('o')); //=> 1
console.log('John Wick'.indexOf('XXX')); //=> -1
console.log(getResults());
console.log(getResults2());

View File

@@ -0,0 +1,36 @@
// Generics - Mit Hilfe von Generics kannst du wiederverwendbare Komponenten erstellen, die mit verschiedenen Datentypen arbeiten können und dabei die Typsicherheit wahren.
{
function identity<T>(value: T): T {
return value;
}
const identity2 = <T>(value: T): T => {
return value;
};
let stringResult = identity<string>('Hello');
let numberResult = identity2<number>(42);
// type Syntax =========
console.log(stringResult, numberResult);
type StringArray = Array<string>; // string[]
type NumberArray = Array<number>; // number[]
let names: StringArray = ['Tick', 'Trick', 'Track'];
let names2: string[] = ['Tick', 'Trick', 'Track'];
let lottoNumbers: NumberArray = [12, 4, 16, 45, 23, 19];
let lottoNumbers2: Array<number> = [12, 4, 16, 45, 23, 19];
let lottoNumbers3: number[] = [12, 4, 16, 45, 23, 19];
console.log(names, names2, lottoNumbers, lottoNumbers2, lottoNumbers3);
let namesWithAges: Array<string | number> = ['Bob', 23, 'Alice', 44];
let namesWithAges2: (string | number)[] = ['Bob', 23, 'Alice', 44];
console.log('namesWithAges:', namesWithAges);
console.log('namesWithAges2:', namesWithAges2);
}

View File

@@ -0,0 +1,23 @@
// Static Type Checking
{
const data = [1, 2, 3, 4, 5, 6];
console.log(data.length);
// Fehler wird bereits während der Laufzeit (im statischen Umfeld) angezeigt
// data(); // This expression is not callable.
// data.toLowerCase(); // Property 'toLowerCase' does not exist on type 'number[]'.
const liEls = document.querySelectorAll('li');
// Property 'addEventListener' does not exist on type 'NodeListOf<HTMLLIElement>'.
// liEls.addEventListener('click', (e) => {
// console.log('click');
// });
liEls?.forEach((el) => {
el.addEventListener('click', (e) => {
console.log('click');
});
});
}

View File

@@ -0,0 +1,16 @@
// Type Definition für Funktionen
{
interface ShoppingCart {
getTotal: () => number;
}
function calculateTotal(cart: ShoppingCart): number {
// return '123.10'; // Type 'string' is not assignable to type 'number'.
return cart.getTotal();
}
const calculateTotal2 = (cart: ShoppingCart): number => {
// return '123.10'; // Type 'string' is not assignable to type 'number'.
return cart.getTotal();
};
}

View File

@@ -0,0 +1,20 @@
// Optional exception Parameter in JS
{
const vehicle = {
make: 'Toyota',
model: 'Corolla',
// startEngine: function () {
// return `${this.make}: engine startet`;
// },
startEngine() {
return `${this.make}: engine startet`;
},
};
console.log(vehicle.startEngine()); // => 'Toyota: egine startet'
const weather = [{ main: [{ icon: '10dn', description: 'Clouds' }] }];
console.log(weather[0]?.main[0]?.description); // Optionale Parameter
// console.log(weather[0].main[0].description); // TypeError: Cannot read properties of undefined (reading 'main')
}

View File

@@ -0,0 +1,35 @@
{
interface Vehicle {
make: string;
model: string;
startEngine: () => string;
stopEngine?: () => void; // ?: optional Property
}
const vehicle: Vehicle = {
make: 'Toyota',
model: 'Corolla',
startEngine() {
return `${this.make}: engine startet`;
},
};
const vehicle2: Vehicle = {
make: 'Jeep',
model: 'Renegade',
startEngine() {
return `${this.make}: engine startet`;
},
stopEngine() {
console.log(`${this.make}: engine stoppt`);
},
};
console.log(vehicle.startEngine()); // => 'Toyota: engine startet'
// Property Exception
// vehicle.stopEngine(); // Cannot invoke an object which is possibly 'undefined'.
vehicle.stopEngine?.(); // => no error - wird nur ausgeführt, wenn Methode existiert
vehicle2.stopEngine?.(); // 'Jeep: engine stoppt'
}

View File

@@ -0,0 +1,35 @@
// Static Type Checking Part II
{
const calculateArea = (radius: number, pi: string): number => {
return radius ** 2 * parseFloat(pi);
};
console.log(calculateArea(10, '3.14')); // 314
// console.log(calculateArea(10, 3.14)); // Argument of type 'number' is not assignable to parameter of type 'string'.
// Unbenutzte Variablen
const greetUser = (name: string): void => {
const greeting = 'Hello, ' + name;
const timestamp = new Date(); // Unused variable // 'timestamp' is declared but its value is never read.
console.log(greeting);
};
greetUser('John Wick');
// Logikfehler in bedingten Anweisungen
const dayOfWeek = new Date().getDay(); // number
let message = '';
if (dayOfWeek === 0 || dayOfWeek === 6) {
message = "It's a weekend!";
// This comparison appears to be unintentional because the types 'number' and 'string' have no overlap.
// } else if (dayOfWeek === 2 || dayOfWeek === 'Tuesday') {
// message = "It's Tuesday!";
} else if (dayOfWeek === 2) {
message = "It's Tuesday!";
}
}

View File

@@ -0,0 +1,31 @@
// Explicit Type Annotations - In TypeScript hast du die Möglichkeit, die Typen von Variablen und Funktionsparametern explizit zu definieren.
{
let age: number = 23;
let message: string = 'Welcome Text';
let toggle: boolean = true;
// function welcome(employee: string, hireDate: Date) {
// console.log(`Welcome ${employee}, your hire date is ${hireDate.toDateString()}!`);
// }
const logWelcome = (employee: string, hireDate: Date): void => {
console.log(`Welcome ${employee}, your hire date is ${hireDate.toDateString()}!`);
};
// Argument of type 'number' is not assignable to parameter of type 'Date'.
// logWelcome('John Wick', 2024);
logWelcome('John Wick', new Date('2024'));
type Employee = { name: string; startDate: Date; salary: number };
const processEmployee = (employee: Employee): void => {
console.log(
`${employee.name} started on ${employee.startDate.toDateString()} with a salary of $${employee.salary}.`,
);
};
// Type 'string' is not assignable to type 'number'.
// processEmployee({ name: 'John', startDate: new Date('2026-07-20'), salary: '50k' });
processEmployee({ name: 'John', startDate: new Date('2026-07-20'), salary: 50000 });
}

View File

@@ -0,0 +1,33 @@
// Type Inference - automatisches erkennen der Datentypen bei Zuweisung
{
let greeting = 'Hello World';
// greeting = 123; // Type 'number' is not assignable to type 'string'.
let count = 123; // inferred as number
let isCompleted = true; //inferred as boolean
const isSmoking = true; // inferred as literal true
const houseNumber = 33; // inferred as literal 33
let age: number = 40; // explicit type annotation as number
let names = ['Andreas', 'Kahleel', 'Ersin', 'Adel']; // inferred as string[]
let namesInUpperCase = names.map((name) /* inferred as string */ => {
return name.toUpperCase();
}); // inferred as string[]
console.log(namesInUpperCase.join(', '));
let currentMessageNumber: number; // explicit type annotation as number
let randomValue; // inferred as 'any'
let randomNumber: any; // explicit type annotation as 'any'
randomNumber = 'hello';
randomNumber = 123;
randomNumber = true;
randomNumber = () => 'test';
}