diff --git a/Les04-TypeScript-Fundamentals/Les04-Docenttekst.md b/Les04-TypeScript-Fundamentals/Les04-Docenttekst.md index af4bc99..3e98660 100644 --- a/Les04-TypeScript-Fundamentals/Les04-Docenttekst.md +++ b/Les04-TypeScript-Fundamentals/Les04-Docenttekst.md @@ -977,31 +977,28 @@ _[Pauzeer. Maak oogcontact.]_ "Huiswerk voor volgende week:" -_[Schrijf op en stuur ook via email/Canvas:]_ +_[Schrijf op en stuur ook via email/Teams:]_ "**Huiswerk Les 4:** -1. **Finish all 8 TypeScript Escaperoom rooms** (if not done today) -2. **Download de JS→TS Converter zip** van Canvas - - Convert 3-5 JavaScript files to TypeScript - - Voeg types toe aan alle functies en variabelen - - Zorg dat TypeScript compiler 0 errors geeft -3. **Prepare for Les 5** — TypeScript + React - - Denk: hoe zouden je React props getypeerd worden? +1. **Download `les4-huiswerk-js-converter.zip`** van Teams +2. Je krijgt 4 JavaScript bestanden: users, products, orders, utils +3. Zet ze allemaal om naar TypeScript — interfaces schrijven, union types, functies typen +4. De tests staan al in TypeScript — die zijn je hints! +5. `npm run check` moet 0 errors geven, `npm test` moet groen zijn +6. **Geen `any`!** Als ik `any` zie, stuur ik het terug. -Room 1-8 van de escaperoom moet af. Als je niet klaar bent vandaag, je hebt de week om het af te maken. Volgende week bouw je hierop voort." +En als je de escaperoom nog niet af hebt: maak die ook af." _[Toon Slide 22 preview.]_ -"**Volgende week: Les 5. TypeScript + React.**" +"**Volgende week: Les 5. TypeScript voor React.**" -"Jullie weten nu: types voorkomen fouten. Functies typen. Interfaces. Volgende week: React components. Props zijn... functies. Dus: props typen. useState? Het returned state EN een setter — beide getypd. Events? Handlers getypd." - -"**TypeScript + React = superkracht.** Cursor snapt je code beter. Minder bugs. Betere autocomplete." +"Jullie weten nu de basis: types, interfaces, union types, functies typen. Volgende week pakken we het volgende level: hoe gebruik je TypeScript in React? Props typen, useState met types, event handlers, API calls. Dat is de laatste stap voordat we in Les 6 met Next.js beginnen." _[Maak oogcontact, glimlach.]_ -"Jullie hebben vandaag veel geleerd. TypeScript lijkt misschien veel regels. Maar denk eraan: elke rode squiggle is TypeScript die zegt: 'Hé, ik help je.' Niet iets wat boos is. Het is helpful." +"Jullie hebben vandaag veel geleerd. TypeScript lijkt misschien veel regels. Maar denk eraan: elke rode squiggle is TypeScript die zegt: 'Hé, ik help je.' Het is niet boos — het is helpful." "Goed gedaan vandaag. Tot volgende keer!" diff --git a/Les04-TypeScript-Fundamentals/Les04-Slide-Overzicht.md b/Les04-TypeScript-Fundamentals/Les04-Slide-Overzicht.md index d14ec4c..3034189 100644 --- a/Les04-TypeScript-Fundamentals/Les04-Slide-Overzicht.md +++ b/Les04-TypeScript-Fundamentals/Les04-Slide-Overzicht.md @@ -709,31 +709,28 @@ En oefening. Je bent nooit klaar met TypeScript. Er is altijd meer om te leren. ### Op de Slide **Huiswerk (les 4):** -- Finaliseer zoveel escaperoom kamers als je kan -- Verzend je TypeScript file naar me (geen `any`!) -- Lees het TypeScript Handbook intro (5 minuten) +- Download `les4-huiswerk-js-converter.zip` van Teams +- Zet 4 JavaScript bestanden om naar TypeScript +- Schrijf interfaces, union types, typed functies +- `npm run check` = 0 errors, `npm test` = groen +- Geen `any` toegestaan! -**Preview les 5 - Next.js Basics:** -- Next.js setup -- File-based routing -- Eerste pagina's maken -- TypeScript in Next.js -- Deploy naar Vercel +**Preview les 5 - TypeScript voor React:** +- Generics & utility types +- Props & state typen in React +- Event handlers & async functies typen +- API responses typen met `Promise` -Visual: Next.js logo met pijl naar "Les 5" +Visual: TypeScript logo → React logo → "Les 5" ### Docentnotities -"Huiswerk: finaliseer die escaperoom. Verzend je file naar me. Ik wil geen `any` zien, anders stuur ik het terug! +"Huiswerk: jullie krijgen een JavaScript project met 4 bestanden — users, products, orders, utils. Alles moet omgezet worden naar TypeScript. Interfaces schrijven, union types gebruiken, functies typen. De tests staan al in TypeScript, die vertellen je wat de verwachte types zijn. `npm run check` moet 0 errors geven en `npm test` moet groen zijn. Geen `any`! -En lees het TypeScript Handbook intro. Niet heel veel tijd, maar het helpt je context. +Volgende les gaan we verder met TypeScript, maar dan voor React. Hoe type je props? Hoe werkt useState met types? Hoe type je een API call? Dat is de brug naar Les 6, waar we beginnen met Next.js. -Volgende les? NEXT.JS. Dit is waar het echt spannend wordt. Jullie gaan echte web apps bouwen met React, TypeScript, en all the bells and whistles. +Dus zorg dat je huiswerk doet — je hebt die basis nodig. -Next.js is het framework dat everyone uses. Vercel (de makers) gebruiken het. Jullie gaan het morgen gebruiken. - -Dus zorg dat je huiswerk doet. Het volgende is big. - -Goed werk vandaag! Ik ben trots op jullie. Tot volgende keer!" +Goed werk vandaag! Tot volgende keer!" --- diff --git a/Samenvattingen/Les05-Samenvatting.md b/Samenvattingen/Les05-Samenvatting.md index d580888..2ecb342 100644 --- a/Samenvattingen/Les05-Samenvatting.md +++ b/Samenvattingen/Les05-Samenvatting.md @@ -1,393 +1,234 @@ -# Les 5: TypeScript Basics +# Les 5: TypeScript voor React --- ## Hoofdstuk -**Deel 2: Technical Foundations** (Les 5-9) +**Deel 2: Technical Foundations** (Les 4-9) ## Beschrijving -Introductie tot TypeScript voor React developers. Leer waarom TypeScript waardevol is, hoe je types schrijft, en hoe je het combineert met React. +Verdieping in TypeScript met focus op React-patronen. Studenten leren generics, utility types, en hoe je React components, hooks, events en API calls correct typt. Voorbereiding op Les 6 waar ze met Next.js aan de slag gaan. + +**Voorkennis:** Les 4 (TypeScript Fundamentals) — basic types, interfaces, union types, type aliases, functies typen. --- ## Te Behandelen -### Waarom TypeScript? - -**Het probleem met JavaScript:** -```javascript -function greet(name) { - return "Hello, " + name.toUpperCase(); -} - -greet(42); // Runtime error! 42.toUpperCase is not a function -``` - -**De oplossing met TypeScript:** -```typescript -function greet(name: string): string { - return "Hello, " + name.toUpperCase(); -} - -greet(42); // Compile error! Argument of type 'number' is not assignable to type 'string' -``` - -**Voordelen:** -- Fouten vinden VOORDAT je code runt -- Betere autocomplete in je editor -- Code is zelf-documenterend -- AI tools begrijpen je code beter - ---- - -### Basic Types +### Generics (20 min) +- Waarom generics? Herbruikbare, type-safe code +- `Array`, `Promise` — generics die ze al kennen +- Eigen generics schrijven: `function getFirst(items: T[]): T` +- Generics met constraints: `` +- `keyof` operator: `function getValue(obj: T, key: K): T[K]` ```typescript -// Primitives -let name: string = "Tim"; -let age: number = 25; -let isStudent: boolean = true; +// Generic functie +function wrapInArray(value: T): T[] { + return [value]; +} -// Arrays -let numbers: number[] = [1, 2, 3]; -let names: string[] = ["Tim", "Anna"]; +wrapInArray("hello"); // string[] +wrapInArray(42); // number[] -// Alternative array syntax -let scores: Array = [90, 85, 88]; - -// Objects -let user: { name: string; age: number } = { - name: "Tim", - age: 25 -}; +// Met constraint +function getProperty(obj: T, key: K): T[K] { + return obj[key]; +} ``` --- -### Type Inference - -TypeScript raadt types vaak zelf: - -```typescript -// TypeScript weet dat dit een string is -let message = "Hello"; // type: string - -// TypeScript weet dat dit een number is -let count = 42; // type: number - -// TypeScript weet wat de functie returned -function double(x: number) { - return x * 2; // return type: number (inferred) -} -``` - -**Regel:** Je hoeft niet altijd types te schrijven. Laat TypeScript inferren waar mogelijk. - ---- - -### Interfaces - -Voor het beschrijven van object shapes: +### Utility Types (15 min) +- `Partial` — alle properties optioneel (handig voor updates) +- `Pick` — selecteer specifieke properties +- `Omit` — alles behalve specifieke properties +- `Record` — key-value mapping +- Praktisch voorbeeld: `updateUser(id: string, data: Partial)` ```typescript interface User { - id: number; + id: string; name: string; email: string; - isActive: boolean; + age: number; } -const user: User = { - id: 1, - name: "Tim", - email: "tim@example.com", - isActive: true -}; +// Partial: voor update functies +function updateUser(id: string, updates: Partial): User { ... } +updateUser("1", { name: "Tim" }); // alleen name updaten -// Optional properties met ? -interface Product { - id: number; - name: string; - price: number; - description?: string; // optioneel -} +// Omit: voor create functies (id wordt server-side gegenereerd) +type CreateUserInput = Omit; + +// Pick: voor specifieke views +type UserPreview = Pick; ``` --- -### Type Aliases - -Alternatief voor interfaces, meer flexibel: +### React Props Typen (20 min) +- Interface voor component props +- Children typen met `React.ReactNode` +- Callback props: `onClick: () => void`, `onChange: (value: string) => void` +- Spread props en prop forwarding +- Default values met destructuring ```typescript -// Type alias voor object -type User = { - id: number; - name: string; -}; - -// Type alias voor union types -type Status = "pending" | "approved" | "rejected"; - -// Type alias voor functie -type GreetFunction = (name: string) => string; -``` - -**Interface vs Type:** -- Interface: voor objecten, kan extended worden -- Type: voor alles, meer flexibel - ---- - -### TypeScript met React - -**Props typen:** - -```typescript -// Interface voor props -interface ButtonProps { - label: string; - onClick: () => void; - disabled?: boolean; +interface CardProps { + title: string; + children: React.ReactNode; + variant?: "default" | "highlighted"; + onClose?: () => void; } -// Component met typed props -function Button({ label, onClick, disabled = false }: ButtonProps) { +function Card({ title, children, variant = "default", onClose }: CardProps) { return ( - - ); -} - -// Gebruik - +
+

{title}

+ {onClose && } + {children}
); } ``` -Zet dit om naar TypeScript: -1. Maak `Product` interface -2. Maak `ProductCardProps` interface -3. Type de component -4. Fix alle TypeScript errors +--- -**Deel 2: Interfaces Schrijven (30 min)** +### useState & useEffect Typen (15 min) +- Type inference bij useState: `useState(0)` → number +- Explicit types: `useState(null)` +- Arrays: `useState([])` +- useEffect met async patterns -Maak interfaces voor: +```typescript +const [user, setUser] = useState(null); +const [products, setProducts] = useState([]); +const [loading, setLoading] = useState(false); // inference: boolean -1. **User** met: id, name, email, avatar (optioneel), createdAt -2. **Product** met: id, name, price, description (optioneel), inStock, category -3. **Order** met: id, userId, products (array), total, status (pending/shipped/delivered) +useEffect(() => { + async function fetchData() { + setLoading(true); + const response = await fetch("/api/users"); + const data: User[] = await response.json(); + setUsers(data); + setLoading(false); + } + fetchData(); +}, []); +``` -**Deel 3: React Component met Types (45 min)** +--- -Bouw een `UserList` component: -- Props: users array, onSelectUser callback -- State: selectedUserId (number of null) -- Toon lijst van users, highlight geselecteerde +### Event Handlers Typen (10 min) +- `React.ChangeEvent` +- `React.FormEvent` +- `React.MouseEvent` +- Tip: hover in Cursor om het juiste event type te vinden -Alle types moeten correct zijn. Geen `any` gebruiken! +```typescript +function SearchForm() { + const [query, setQuery] = useState(""); -### Deliverable -- ProductCard.tsx met correcte types -- types.ts met alle interfaces -- UserList.tsx volledig getypt + const handleChange = (e: React.ChangeEvent) => { + setQuery(e.target.value); + }; + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + console.log("Searching:", query); + }; + + return ( +
+ +
+ ); +} +``` + +--- + +### API Responses & Async Typen (15 min) +- `Promise` voor async functies +- API response types definiëren +- Error handling met types +- Fetch wrapper met generics + +```typescript +interface ApiResponse { + data: T; + status: number; + message: string; +} + +async function fetchApi(url: string): Promise> { + const response = await fetch(url); + if (!response.ok) { + throw new Error(`HTTP error: ${response.status}`); + } + return response.json(); +} + +// Gebruik +const { data: users } = await fetchApi("/api/users"); +const { data: product } = await fetchApi("/api/products/1"); +``` + +--- + +## Tools +- Cursor (Student Plan) +- TypeScript +- React (via CDN of Vite) + +--- + +## Lesopdracht (75 min) + +### Typed React Dashboard + +Studenten bouwen een kleine React-app met volledig getypte components: + +**Opdracht:** Bouw een Product Dashboard met: + +1. **`ProductCard` component** — props: Product interface, onAddToCart callback +2. **`ProductList` component** — props: Product[], filterCategory (union type) +3. **`SearchBar` component** — props: query string, onChange handler (getypt event) +4. **`useProducts` custom hook** — fetch products, return `{ products, loading, error }` +5. **Alle types in een apart `types.ts` bestand** + +**Vereisten:** +- Geen `any` toegestaan +- Alle event handlers correct getypt +- useState met expliciete types waar nodig +- Minstens 1 generic functie (bijv. een `sortBy` of `filterBy`) --- ## Huiswerk (2 uur) -### TypeScript Verdieping +### Extend het Dashboard -**Deel 1: Drie Components Bouwen (1 uur)** +Bouw voort op de lesopdracht: -Bouw volledig in TypeScript: - -1. **SearchInput** component - - Props: value, onChange, placeholder (optioneel) - - Volledig getypt - -2. **DataTable** component - - Generic: werkt met elk type data - - Props: data array, columns config - - Type-safe rendering - -3. **Modal** component - - Props: isOpen, onClose, title, children - - Correct gebruik van React.ReactNode - -**Deel 2: Eindproject Interfaces (30 min)** - -Bedenk de data structuur voor je eindproject: -- Welke entiteiten heb je? (users, posts, products, etc.) -- Maak interface voor elke entiteit -- Documenteer relaties tussen entiteiten - -**Deel 3: Cheat Sheet (30 min)** - -Maak persoonlijke TypeScript cheat sheet: -- Meest gebruikte types -- Interface vs Type wanneer -- Common patterns met React -- Hoe je errors oplost +1. **Shopping Cart** toevoegen met getypte state (`CartItem[]`) +2. **API simulatie** — maak een `fetchProducts()` functie met `Promise` +3. **Utility types gebruiken** — `Partial` voor updates, `Omit` voor create +4. **Bonus: Generic `DataTable` component** — werkt met elke array van objecten ### Deliverable -- 3 TypeScript components -- types/index.ts met eindproject interfaces -- TypeScript cheat sheet (1 pagina) +- Werkend React project met TypeScript +- Alle components volledig getypt +- `npm run check` = 0 errors --- ## Leerdoelen Na deze les kan de student: -- Uitleggen waarom TypeScript waardevol is -- Basic types gebruiken (string, number, boolean, arrays) -- Interfaces en type aliases schrijven -- React components typen met props -- useState met types gebruiken -- Generics op basisniveau begrijpen -- JavaScript code omzetten naar TypeScript -- TypeScript errors lezen en oplossen +- Generics schrijven en toepassen +- Utility types gebruiken (Partial, Pick, Omit, Record) +- React component props correct typen +- useState en useEffect met types gebruiken +- Event handlers typen (ChangeEvent, FormEvent, MouseEvent) +- Async functies en API responses typen met Promise +- Een custom hook schrijven met correcte return types