diff --git a/src/05-forgeschrittenes-typsystem/KATA1/solution.ts b/src/05-forgeschrittenes-typsystem/KATA1/solution.ts new file mode 100644 index 0000000..b994d3c --- /dev/null +++ b/src/05-forgeschrittenes-typsystem/KATA1/solution.ts @@ -0,0 +1,86 @@ +// 1. Union Types & Intersection Types +type User = { name: string; email: string }; +type Admin = { name: string; adminLevel: number }; +type Person = { name: string; age: number }; +type Worker = { employeeId: number }; + +type UserOrAdmin = User | Admin; +type Employee = Person & Worker; + +// 2. Discriminated Unions +type Circle = { kind: 'circle'; radius: number }; +type Rectangle = { kind: 'rectangle'; width: number; height: number }; + +type Shape = Circle | Rectangle; + +function calculateArea(shape: Shape): number { + switch (shape.kind) { + case 'circle': + return Math.PI * shape.radius ** 2; + case 'rectangle': + return shape.width * shape.height; + } +} + +// 3. Tuple Types +type Coordinate = [number, number]; + +function getDistance(a: Coordinate, b: Coordinate): number { + const dx = a[0] - b[0]; + const dy = a[1] - b[1]; + return Math.sqrt(dx ** 2 + dy ** 2); +} + +// 4. Mapped Types & Utility Types +type ReadonlyPerson = Readonly; + +function updatePerson(person: ReadonlyPerson) { + // person.age = 30; Fehler: Readonly verhindert Änderungen + console.log('Kann nicht geändert werden!'); +} + +// 5. Conditional Types +type IsString = T extends string + ? 'Ja' + : unknown extends T + ? 'unbekannt' + : 'Nein'; + +type Test1 = IsString; // "Ja" +type Test2 = IsString; // "Nein" +type Test3 = IsString; // "Unbekannt" + +// 6. Type Guards +function isString(value: unknown): value is string { + return typeof value === 'string'; +} + +function printUpperCase(value: unknown): void { + if (isString(value)) { + console.log(value.toUpperCase()); + } else { + console.log('Kein String'); + } +} + +// Bonus Challenge: Erweiterter Type Guard mit mehreren Typen +type Car = { type: 'car'; speed: number }; +type Vehicle = Car | { type: 'bike'; gear: number }; + +function isCar(vehicle: Vehicle): vehicle is Car { + return vehicle.type === 'car'; +} + +function describeVehicle(vehicle: Vehicle) { + if (isCar(vehicle)) { + console.log(`Auto mit Geschwindigkeit: ${vehicle.speed} km/h`); + } else { + console.log(`Fahrrad mit Gangzahl: ${vehicle.gear}`); + } +} + +const myCar: Vehicle = { type: 'car', speed: 120 }; +const myBike: Vehicle = { type: 'bike', gear: 21 }; + +describeVehicle(myCar); // "Auto mit Geschwindigkeit: 120 km/h" +describeVehicle(myBike); // "Fahrrad mit Gangzahl: 21" diff --git a/src/05-forgeschrittenes-typsystem/KATA2/starter.ts b/src/05-forgeschrittenes-typsystem/KATA2/starter.ts index ce15e00..889e5de 100644 --- a/src/05-forgeschrittenes-typsystem/KATA2/starter.ts +++ b/src/05-forgeschrittenes-typsystem/KATA2/starter.ts @@ -15,10 +15,10 @@ type ReadonlyExceptType = ReadonlyExcept; // { readonly timestamp: number; type: string; } // 3. KeysOfType -type Settings = { darkMode: boolean; fontSize: number }; +type Settings = { darkMode: boolean; isActive: boolean; fontSize: number }; type KeysOfType = any; type KeysWithBoolean = KeysOfType; -// Erwartet: "darkMode" +// Erwartet: "darkMode" | "isActive" // 4. NumberKeys type Employee = { id: number; name: string; salary: number };