# KATA: Fortgeschrittenes Typsystem in TypeScript

## Ziel

In dieser KATA wiederholen wir das Gelernte über **Union Types, Intersection Types, Discriminated Unions, Tuple Types, Mapped Types, Conditional Types, Utility Types und Type Guards**. 


## Aufgaben

### 1. Union Types & Intersection Types
**Aufgabe:**
- Erstelle eine Union `UserOrAdmin`, die entweder einen normalen User oder einen Admin darstellen kann.
- Erstelle eine Intersection `Employee`, die sowohl `Person` als auch `Worker` kombiniert.

```typescript
type User = { name: string; email: string };
type Admin = { name: string; adminLevel: number };
type Person = { name: string; age: number };
type Worker = { employeeId: number };
```

### 2. Discriminated Unions
**Aufgabe:**
- Erstelle eine Discriminated Union `Shape`, die `Circle` und `Rectangle` unterscheidet.
- Implementiere eine Funktion `calculateArea(shape)`, die die Fläche berechnet.

```typescript
type Circle =
type Rectangle =
type Shape =
```

### 3. Tuple Types
**Aufgabe:**
- Erstelle ein `Coordinate`-Tupel.
- Implementiere eine Funktion `getDistance(a, b)`, die die euklidische Distanz berechnet.

```typescript
type Coordinate =
```

### 4. Mapped Types & Utility Types
**Aufgabe:**
- Erstelle einen `ReadonlyPerson`-Typ, der alle `Person`-Eigenschaften schreibgeschützt macht.
- Implementiere eine Funktion `updatePerson(person)`, die versucht, eine Eigenschaft zu ändern.

```typescript
type ReadonlyPerson =
```

### 5. Conditional Types
**Aufgabe:**
- Erstelle einen bedingten Typ `IsString<T>`, der "Ja" für `string` zurückgibt und "Nein" für andere Typen.
- Teste ihn mit `string`, `number` und `boolean`.
- Erweitere den Typ so, dass er zusätzlich "Unbekannt" für `unknown` zurückgibt.

```typescript
type IsString<T> =

// Erwartete Ergebnisse:
type Test1 = IsString<>;  // "Ja"
type Test2 = IsString<>;  // "Nein"
type Test3 = IsString<>; // "Unbekannt"
```

### 6. Type Guards
**Aufgabe:**
- Implementiere eine Funktion `isString(value)`, die prüft, ob `value` ein `string` ist.
- Nutze sie in einer weiteren Funktion `printUpperCase(value)`, die `value` groß schreibt, falls es ein `string` ist.

```typescript
function isString(value) {
    // TODO: Implementieren
}

function printUpperCase(value) {
    // TODO: Type Guard nutzen
}
```


## Bonus Challenge

### 7. Erweiterter Type Guard
**Aufgabe:**
- Implementiere eine Discriminated Union `Vehicle`, die `Car` und `Bike` enthält.
- Erstelle eine Funktion `describeVehicle(vehicle: Vehicle)`, die die Eigenschaften des Fahrzeugs beschreibt.
- Nutze einen benutzerdefinierten Type Guard, um zwischen Auto und Fahrrad zu unterscheiden.

```typescript
type Vehicle = { type: "car"; speed: number } | { type: "bike"; gear: number };

function isCar(vehicle) {
    // TODO
}

function describeVehicle(vehicle: Vehicle) {
    if (isCar(vehicle)) {
        // TODO LOG: Auto mit Geschwindigkeit: XY km/h
    } else {
      // TODO LOG: Fahrrad mit Gangzahl: XY
    }
}
```