diff --git a/05_typescript/faq/falsy-values.js b/05_typescript/faq/falsy-values.js new file mode 100644 index 0000000..5ae9fbf --- /dev/null +++ b/05_typescript/faq/falsy-values.js @@ -0,0 +1,6 @@ +const test = []; +if (test) { + console.log('truthy'); +} else { + console.log('falsy'); +} diff --git a/05_typescript/faq/falsy-values.ts b/05_typescript/faq/falsy-values.ts new file mode 100644 index 0000000..5ae9fbf --- /dev/null +++ b/05_typescript/faq/falsy-values.ts @@ -0,0 +1,6 @@ +const test = []; +if (test) { + console.log('truthy'); +} else { + console.log('falsy'); +} diff --git a/05_typescript/unterricht/tag31/01_ts-narrowing-guards/assets/img/what-is-ts.webp b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/assets/img/what-is-ts.webp new file mode 100644 index 0000000..d329dbb Binary files /dev/null and b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/assets/img/what-is-ts.webp differ diff --git a/05_typescript/unterricht/tag31/01_ts-narrowing-guards/assets/js/01_narrowing.js b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/assets/js/01_narrowing.js new file mode 100644 index 0000000..6701eb3 --- /dev/null +++ b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/assets/js/01_narrowing.js @@ -0,0 +1,55 @@ +(() => { + // src/01_narrowing.ts + { + const displayValue = (value) => { + if (typeof value === "string") { + console.log(value.toUpperCase()); + } else { + console.log(value.toFixed(2)); + } + }; + displayValue("Hello World"); + displayValue(19); + const processPadding = (padding, input) => { + if (typeof padding === "number") { + return `${padding * 2}${input}`; + } else { + return `${padding}${input}`; + } + }; + console.log(processPadding(2, "px")); + console.log(processPadding("1.5", "rem")); + console.log(processPadding(10, "%")); + console.log(processPadding("10", "%")); + const handleInput = (input) => { + if (typeof input === "boolean") { + return input ? "The value is true!" : "The value is false."; + } else if (typeof input === "number") { + return `The number is ${input * 10}.`; + } + return `The string is "${input.toUpperCase()}".`; + }; + handleInput(true); + handleInput(10); + handleInput("super"); + const processNumbers = (numbers) => { + numbers?.forEach((num) => console.log(num * 2)); + if (Array.isArray(numbers)) { + numbers.forEach((num) => console.log(num * 2)); + } + }; + processNumbers([1, 2, 3, 4]); + processNumbers(null); + const displayInfo = (input) => { + if (input !== null && typeof input === "object") { + console.log(input.name); + } else { + console.log(input); + } + }; + displayInfo("Error"); + displayInfo({ name: "ErrorHandler" }); + displayInfo(null); + console.log("###"); + } +})(); diff --git a/05_typescript/unterricht/tag31/01_ts-narrowing-guards/assets/js/02_truthiness.js b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/assets/js/02_truthiness.js new file mode 100644 index 0000000..6ba7521 --- /dev/null +++ b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/assets/js/02_truthiness.js @@ -0,0 +1,38 @@ +(() => { + // src/02_truthiness.ts + { + const showMessage = (userCount) => { + return userCount ? `There are ${userCount} users online.` : "No users online."; + }; + console.log(showMessage(5)); + const printNames = (names) => { + if (names) { + names.forEach((name) => console.log(name)); + } else { + console.log("No names provided."); + } + }; + printNames(["Christian", "Florian", "Stefan", "Benjamin"]); + printNames([]); + printNames(null); + const displayInput = (input) => { + if (input) { + console.log(`Input provided: ${input}`); + } else { + console.log("No input provided."); + } + }; + displayInput(document.querySelector("h2")); + displayInput("Hello World"); + displayInput(null); + const multiplyValues = (values, factor) => { + return values ? values.map((value) => value * factor) : void 0; + }; + let numbers; + console.log(multiplyValues([1, 2, 3, 4], 2)); + console.log(multiplyValues([], 2)); + console.log(multiplyValues([], 2)); + console.log(multiplyValues(numbers, 2)); + console.log("###"); + } +})(); diff --git a/05_typescript/unterricht/tag31/01_ts-narrowing-guards/assets/js/03_equality.js b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/assets/js/03_equality.js new file mode 100644 index 0000000..0f31833 --- /dev/null +++ b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/assets/js/03_equality.js @@ -0,0 +1,37 @@ +(() => { + // src/03_equality.ts + { + const compareValues = (a, b) => { + if (a === b) { + console.log(a.toUpperCase()); + console.log(b.toLowerCase()); + } else { + console.log(`a is ${a}, b is ${b}`); + } + }; + const result = compareValues(1, "1"); + console.log(result); + const scaleValue = (container, factor) => { + if (container.value != null) { + container.value *= factor; + } + }; + scaleValue({ value: 123 }, 2); + scaleValue({ value: null }, 1); + const processInput = (input) => { + if (input !== null) { + if (typeof input === "number") { + console.log(`Number input: ${input.toFixed(2)}`); + } else { + console.log(`String input: ${input.toUpperCase()}`); + } + } else { + console.log("No input provided."); + } + }; + processInput(23); + processInput("23"); + processInput(null); + console.log("###"); + } +})(); diff --git a/05_typescript/unterricht/tag31/01_ts-narrowing-guards/assets/js/04_in-operator.js b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/assets/js/04_in-operator.js new file mode 100644 index 0000000..1cd87df --- /dev/null +++ b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/assets/js/04_in-operator.js @@ -0,0 +1,5 @@ +(() => { + // src/04_in-operator.ts + { + } +})(); diff --git a/05_typescript/unterricht/tag31/01_ts-narrowing-guards/index.html b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/index.html new file mode 100644 index 0000000..e99f67d --- /dev/null +++ b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/index.html @@ -0,0 +1,26 @@ + + + + + + TypeScript - Grundlagen + + + + + + + +
+
+

TypeScript - Grundlagen

+

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

+ TypeScript Kreisdiagramm +
+
+ + diff --git a/05_typescript/unterricht/tag31/01_ts-narrowing-guards/package-lock.json b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/package-lock.json new file mode 100644 index 0000000..93e05a3 --- /dev/null +++ b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/package-lock.json @@ -0,0 +1,499 @@ +{ + "name": "01_ts-types", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "01_ts-types", + "version": "1.0.0", + "devDependencies": { + "esbuild": "^0.28.2" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz", + "integrity": "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.2.tgz", + "integrity": "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz", + "integrity": "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.2.tgz", + "integrity": "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz", + "integrity": "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz", + "integrity": "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz", + "integrity": "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz", + "integrity": "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz", + "integrity": "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz", + "integrity": "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz", + "integrity": "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz", + "integrity": "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz", + "integrity": "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz", + "integrity": "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz", + "integrity": "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz", + "integrity": "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz", + "integrity": "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz", + "integrity": "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz", + "integrity": "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz", + "integrity": "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz", + "integrity": "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz", + "integrity": "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz", + "integrity": "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz", + "integrity": "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz", + "integrity": "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz", + "integrity": "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/esbuild": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz", + "integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.2", + "@esbuild/android-arm": "0.28.2", + "@esbuild/android-arm64": "0.28.2", + "@esbuild/android-x64": "0.28.2", + "@esbuild/darwin-arm64": "0.28.2", + "@esbuild/darwin-x64": "0.28.2", + "@esbuild/freebsd-arm64": "0.28.2", + "@esbuild/freebsd-x64": "0.28.2", + "@esbuild/linux-arm": "0.28.2", + "@esbuild/linux-arm64": "0.28.2", + "@esbuild/linux-ia32": "0.28.2", + "@esbuild/linux-loong64": "0.28.2", + "@esbuild/linux-mips64el": "0.28.2", + "@esbuild/linux-ppc64": "0.28.2", + "@esbuild/linux-riscv64": "0.28.2", + "@esbuild/linux-s390x": "0.28.2", + "@esbuild/linux-x64": "0.28.2", + "@esbuild/netbsd-arm64": "0.28.2", + "@esbuild/netbsd-x64": "0.28.2", + "@esbuild/openbsd-arm64": "0.28.2", + "@esbuild/openbsd-x64": "0.28.2", + "@esbuild/openharmony-arm64": "0.28.2", + "@esbuild/sunos-x64": "0.28.2", + "@esbuild/win32-arm64": "0.28.2", + "@esbuild/win32-ia32": "0.28.2", + "@esbuild/win32-x64": "0.28.2" + } + } + } +} diff --git a/05_typescript/unterricht/tag31/01_ts-narrowing-guards/package.json b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/package.json new file mode 100644 index 0000000..e116d3a --- /dev/null +++ b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/package.json @@ -0,0 +1,14 @@ +{ + "name": "01_ts-narrowing-guards", + "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" + } +} diff --git a/05_typescript/unterricht/tag31/01_ts-narrowing-guards/src/01_narrowing.ts b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/src/01_narrowing.ts new file mode 100644 index 0000000..374cd6a --- /dev/null +++ b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/src/01_narrowing.ts @@ -0,0 +1,99 @@ +// Narrowing - Mit Narrowing kann TypeScript innerhalb eines Codeblocks auf einen bestimmten Typ "eingrenzen", sodass du typspezifische Methoden sicher verwenden kannst. +{ + const displayValue = (value: string | number): void => { + // Property 'toUpperCase' does not exist on type 'number'. + // console.log(value.toUpperCase()) + + if (typeof value === 'string') { + console.log(value.toUpperCase()); + // Type Guard: typeof value === "string" + // Narrowing: 'value' is now of type 'string' + } else { + // Narrowing: 'value' is now of type 'number' + console.log(value.toFixed(2)); + } + }; + + displayValue('Hello World'); // => 'HELLO WORLD' + displayValue(19); // => '19.00' + + // ------- + + const processPadding = (padding: string | number, input: string): string => { + // The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type. + // return `${padding * 2}${input}`; + + // Property 'toFixed' does not exist on type 'string | number'. + //Property 'toFixed' does not exist on type 'string'. + // return `${padding.toFixed(2)}${input}`; + + // Narrowing + if (typeof padding === 'number') { + // Here, padding is confirmed to be a number + return `${padding * 2}${input}`; + } else { + // Here, padding is confirmed to be a string + return `${padding}${input}`; + } + }; + + console.log(processPadding(2, 'px')); + console.log(processPadding('1.5', 'rem')); + console.log(processPadding(10, '%')); + console.log(processPadding('10', '%')); + + // -------- + + const handleInput = (input: boolean | number | string): string => { + if (typeof input === 'boolean') { + return input ? 'The value is true!' : 'The value is false.'; + } else if (typeof input === 'number') { + return `The number is ${input * 10}.`; + } + + return `The string is "${input.toUpperCase()}".`; + }; + + handleInput(true); // => 'The value is true!' + handleInput(10); // => 'The number is 100' + handleInput('super'); // => 'The string is super' + + // --------- + + const processNumbers = (numbers: number[] | null) => { + // 'numbers' is possibly 'null'. + // numbers.forEach((num) => console.log(num * 2)); + + numbers?.forEach((num) => console.log(num * 2)); + + // if (numbers !== null && typeof numbers === 'object') { + if (Array.isArray(numbers)) { + numbers.forEach((num) => console.log(num * 2)); + } + }; + + processNumbers([1, 2, 3, 4]); // => 2 4 6 8 + // processNumbers({}); + processNumbers(null); + + // ---------- + + const displayInfo = (input: string | { name: string } | null): void => { + // Property 'name' does not exist on type 'string | { name: string; }'. + //Property 'name' does not exist on type 'string'. + // console.log(input.name); + + if (input !== null && typeof input === 'object') { + console.log(input.name); + } else { + console.log(input); + } + }; + + displayInfo('Error'); + displayInfo({ name: 'ErrorHandler' }); + displayInfo(null); + // displayInfo(123); + + console.log('###'); +} diff --git a/05_typescript/unterricht/tag31/01_ts-narrowing-guards/src/02_truthiness.ts b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/src/02_truthiness.ts new file mode 100644 index 0000000..1488292 --- /dev/null +++ b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/src/02_truthiness.ts @@ -0,0 +1,73 @@ +// Truthiness wird verwendet, um zu bestimmen, ob eine Variable wahr oder falsch ist. + +// Falsy types in TypeScript/JavaScript are: +// - false +// - 0 +// - -0 +// - NaN +// - 0n (BigInt) +// - "" (empty string) +// - null +// - undefined + +{ + const showMessage = (userCount: number): string => { + // if (userCount) { + // return `There are ${userCount} users online.`; + // } + // return 'No users online.'; + + return userCount ? `There are ${userCount} users online.` : 'No users online.'; + }; + + console.log(showMessage(5)); // => There are 5 users online. + + // ------- + + const printNames = (names: string[] | null): void => { + if (names) { + names.forEach((name) => console.log(name)); + } else { + console.log('No names provided.'); + } + }; + + printNames(['Christian', 'Florian', 'Stefan', 'Benjamin']); + printNames([]); + printNames(null); // => 'No names provided.' + // printNames(); // Expected 1 arguments, but got 0. + + // ------- + + const displayInput = (input: string | HTMLHeadingElement | null) => { + if (input) { + console.log(`Input provided: ${input}`); + } else { + console.log('No input provided.'); + } + }; + + displayInput(document.querySelector('h2')); + displayInput('Hello World'); + displayInput(null); + + // -------- + + const multiplyValues = (values: number[] | undefined, factor: number): number[] | undefined => { + // if (!values) { + // return undefined; + // } + // return values.map((value) => value * factor); + + return values ? values.map((value) => value * factor) : undefined; + }; + + let numbers; + + console.log(multiplyValues([1, 2, 3, 4], 2)); // => [2,4,6,8] + console.log(multiplyValues([], 2)); // => [] + console.log(multiplyValues([], 2)); // => [] + console.log(multiplyValues(numbers, 2)); // => undefined + + console.log('###'); +} diff --git a/05_typescript/unterricht/tag31/01_ts-narrowing-guards/src/03_equality.ts b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/src/03_equality.ts new file mode 100644 index 0000000..fb180b6 --- /dev/null +++ b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/src/03_equality.ts @@ -0,0 +1,58 @@ +// Equality - wird verwendet, um zu bestimmen, ob zwei Werte gleich sind. +{ + const compareValues = (a: string | number, b: string | boolean): void => { + // Property 'toUpperCase' does not exist on type 'string | number'. + // Property 'toUpperCase' does not exist on type 'number'. + // console.log(a.toUpperCase()); + + // equality narrowing + if (a === b) { + console.log(a.toUpperCase()); + console.log(b.toLowerCase()); + } else { + console.log(`a is ${a}, b is ${b}`); + } + }; + + // const result = compareValues('1', 1); + const result = compareValues(1, '1'); + + console.log(result); + + // Loose equality + + interface Container { + value: number | null | undefined; + } + + // kein strikter Vergleich (BAD PRACTICE) + const scaleValue = (container: Container, factor: number): void => { + // Douglas Crockford considers the + // == (loose equality) operator to be "bad" because of its inconsistent and surprising behavior, particularly its lack of transitivity, which can lead to unexpected results in JavaScript. He advises against using == and its counterpart != in favor of the strict equality operators === and !== for clearer and safer code + if (container.value != null) { + container.value *= factor; + } + }; + + scaleValue({ value: 123 }, 2); + scaleValue({ value: null }, 1); + + // ------ + const processInput = (input: string | number | null): void => { + if (input !== null) { + if (typeof input === 'number') { + console.log(`Number input: ${input.toFixed(2)}`); + } else { + console.log(`String input: ${input.toUpperCase()}`); + } + } else { + console.log('No input provided.'); + } + }; + + processInput(23); // => 'Number input: 23.00' + processInput('23'); // => 'String input: 23' + processInput(null); // => 'No input provided.' + + console.log('###'); +} diff --git a/05_typescript/unterricht/tag31/01_ts-narrowing-guards/src/04_in-operator.ts b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/src/04_in-operator.ts new file mode 100644 index 0000000..92a7231 --- /dev/null +++ b/05_typescript/unterricht/tag31/01_ts-narrowing-guards/src/04_in-operator.ts @@ -0,0 +1,5 @@ +// In Operator - wird verwendet, um zu bestimmen, ob ein Objekt ein bestimmtes Property hat. +{ + type Car = { drive: () => void }; + type Boat = { sail: () => void }; +}