fix: implement lessons feedback
This commit is contained in:
@@ -1,307 +1,393 @@
|
||||
# Les 5: AI Tool Selection & Workflows
|
||||
# Les 5: TypeScript Basics
|
||||
|
||||
---
|
||||
|
||||
## Hoofdstuk
|
||||
**Hoofdstuk 2: Intermediate** (Les 4-9)
|
||||
**Deel 2: Technical Foundations** (Les 5-9)
|
||||
|
||||
## Beschrijving
|
||||
Leer de sterke en zwakke punten van elke AI tool kennen. Ontwikkel een framework om de juiste tool te kiezen voor de juiste taak en bouw je eigen workflow.
|
||||
Introductie tot TypeScript voor React developers. Leer waarom TypeScript waardevol is, hoe je types schrijft, en hoe je het combineert met React.
|
||||
|
||||
---
|
||||
|
||||
## Te Behandelen
|
||||
|
||||
### Waarom Tool Selection Belangrijk Is
|
||||
### Waarom TypeScript?
|
||||
|
||||
Je kent nu meerdere AI tools:
|
||||
- ChatGPT (brainstormen, planning, uitleg)
|
||||
- Claude (lange context, nuance, analyse)
|
||||
- v0.dev (UI prototyping)
|
||||
- OpenCode (code schrijven met project context)
|
||||
|
||||
**Het probleem:** Elke tool heeft sterke en zwakke punten. De juiste tool kiezen bespaart tijd en levert betere resultaten.
|
||||
|
||||
---
|
||||
|
||||
### Tool Vergelijking
|
||||
|
||||
| Tool | Sterk in | Minder sterk in | Kosten |
|
||||
|------|----------|-----------------|--------|
|
||||
| **ChatGPT** | Brainstormen, uitleg, planning, algemene kennis | Grote codebases, lange context | Gratis / Pro €20/maand |
|
||||
| **Claude** | Lange documenten, nuance, analyse, veiligheid | Soms te voorzichtig, geen images genereren | Gratis / Pro $20/maand |
|
||||
| **v0.dev** | UI components, snel prototypen, Tailwind | Complexe logica, backend | Gratis tier |
|
||||
| **OpenCode** | Code schrijven, project context, terminal | Geen web access, geen images | Gratis |
|
||||
|
||||
---
|
||||
|
||||
### Tool Selection Framework
|
||||
|
||||
**Stap 1: Identificeer de taak**
|
||||
- Wat wil je bereiken?
|
||||
- Hoe complex is het?
|
||||
- Hoeveel context is nodig?
|
||||
|
||||
**Stap 2: Kies de juiste tool**
|
||||
**Het probleem met JavaScript:**
|
||||
```javascript
|
||||
function greet(name) {
|
||||
return "Hello, " + name.toUpperCase();
|
||||
}
|
||||
|
||||
greet(42); // Runtime error! 42.toUpperCase is not a function
|
||||
```
|
||||
Als je wilt... Gebruik...
|
||||
─────────────────────────────────────────────────
|
||||
Brainstormen over een idee → ChatGPT
|
||||
Een lange codebase analyseren → Claude
|
||||
Snel een UI component maken → v0.dev
|
||||
Code schrijven met project context → OpenCode
|
||||
Een complex document begrijpen → Claude
|
||||
Uitleg krijgen over een concept → ChatGPT
|
||||
React component met styling → v0.dev
|
||||
Feature implementeren in project → OpenCode
|
||||
|
||||
**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
|
||||
|
||||
```typescript
|
||||
// Primitives
|
||||
let name: string = "Tim";
|
||||
let age: number = 25;
|
||||
let isStudent: boolean = true;
|
||||
|
||||
// Arrays
|
||||
let numbers: number[] = [1, 2, 3];
|
||||
let names: string[] = ["Tim", "Anna"];
|
||||
|
||||
// Alternative array syntax
|
||||
let scores: Array<number> = [90, 85, 88];
|
||||
|
||||
// Objects
|
||||
let user: { name: string; age: number } = {
|
||||
name: "Tim",
|
||||
age: 25
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Workflow Patterns
|
||||
### Type Inference
|
||||
|
||||
**Pattern 1: Planning → Prototyping → Implementation**
|
||||
```
|
||||
1. ChatGPT: Brainstorm features, maak planning
|
||||
2. v0.dev: Genereer UI prototypes
|
||||
3. OpenCode: Implementeer met project context
|
||||
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)
|
||||
}
|
||||
```
|
||||
|
||||
**Pattern 2: Research → Design → Build**
|
||||
```
|
||||
1. ChatGPT/Claude: Research beste aanpak
|
||||
2. v0.dev: Design components
|
||||
3. OpenCode: Bouw en integreer
|
||||
```
|
||||
**Regel:** Je hoeft niet altijd types te schrijven. Laat TypeScript inferren waar mogelijk.
|
||||
|
||||
**Pattern 3: Quick Iteration**
|
||||
```
|
||||
1. v0.dev: Snel component genereren
|
||||
2. OpenCode: Aanpassen en integreren
|
||||
3. Repeat
|
||||
---
|
||||
|
||||
### Interfaces
|
||||
|
||||
Voor het beschrijven van object shapes:
|
||||
|
||||
```typescript
|
||||
interface User {
|
||||
id: number;
|
||||
name: string;
|
||||
email: string;
|
||||
isActive: boolean;
|
||||
}
|
||||
|
||||
const user: User = {
|
||||
id: 1,
|
||||
name: "Tim",
|
||||
email: "tim@example.com",
|
||||
isActive: true
|
||||
};
|
||||
|
||||
// Optional properties met ?
|
||||
interface Product {
|
||||
id: number;
|
||||
name: string;
|
||||
price: number;
|
||||
description?: string; // optioneel
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Praktijk: Dezelfde Taak, Drie Tools
|
||||
### Type Aliases
|
||||
|
||||
**Opdracht:** Bouw een Contact Form component
|
||||
Alternatief voor interfaces, meer flexibel:
|
||||
|
||||
**Met ChatGPT:**
|
||||
```
|
||||
Prompt: Ik wil een contact form maken met React en Tailwind.
|
||||
Velden: naam, email, bericht. Validatie nodig.
|
||||
Geef me de code en leg uit hoe het werkt.
|
||||
```
|
||||
→ Krijg: Uitleg + code, maar zonder project context
|
||||
```typescript
|
||||
// Type alias voor object
|
||||
type User = {
|
||||
id: number;
|
||||
name: string;
|
||||
};
|
||||
|
||||
**Met v0.dev:**
|
||||
```
|
||||
Prompt: Modern contact form with name, email, message fields.
|
||||
Tailwind styling, validation, responsive design.
|
||||
```
|
||||
→ Krijg: Visueel prototype, direct te gebruiken
|
||||
// Type alias voor union types
|
||||
type Status = "pending" | "approved" | "rejected";
|
||||
|
||||
**Met OpenCode:**
|
||||
// Type alias voor functie
|
||||
type GreetFunction = (name: string) => string;
|
||||
```
|
||||
Prompt: Maak een ContactForm component in src/components/
|
||||
met naam, email en bericht velden. Gebruik onze bestaande
|
||||
Input en Button components. Voeg Zod validatie toe.
|
||||
```
|
||||
→ Krijg: Geïntegreerde code die past in je project
|
||||
|
||||
**Interface vs Type:**
|
||||
- Interface: voor objecten, kan extended worden
|
||||
- Type: voor alles, meer flexibel
|
||||
|
||||
---
|
||||
|
||||
### Wanneer Combineer Je Tools?
|
||||
### TypeScript met React
|
||||
|
||||
**Scenario 1: Nieuwe feature bouwen**
|
||||
1. ChatGPT: "Hoe zou je een dark mode toggle implementeren in React?"
|
||||
2. v0.dev: "Dark mode toggle component with smooth transition"
|
||||
3. OpenCode: "Integreer deze toggle in onze navbar, sla preference op in localStorage"
|
||||
**Props typen:**
|
||||
|
||||
**Scenario 2: Bug oplossen**
|
||||
1. OpenCode: Vraag om bug te identificeren
|
||||
2. Claude: Als de foutmelding complex is, vraag om uitleg
|
||||
3. OpenCode: Implementeer de fix
|
||||
```typescript
|
||||
// Interface voor props
|
||||
interface ButtonProps {
|
||||
label: string;
|
||||
onClick: () => void;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
**Scenario 3: Nieuwe technologie leren**
|
||||
1. ChatGPT: "Leg uit hoe React Server Components werken"
|
||||
2. v0.dev: "Example of React Server Component with data fetching"
|
||||
3. OpenCode: "Help me dit toe te passen in mijn Next.js project"
|
||||
// Component met typed props
|
||||
function Button({ label, onClick, disabled = false }: ButtonProps) {
|
||||
return (
|
||||
<button onClick={onClick} disabled={disabled}>
|
||||
{label}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
// Gebruik
|
||||
<Button label="Click me" onClick={() => console.log("Clicked!")} />
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Anti-Patterns (Wat Niet Te Doen)
|
||||
### useState met Types
|
||||
|
||||
**❌ Verkeerde tool voor de taak:**
|
||||
- ChatGPT vragen om een hele app te bouwen → te weinig context
|
||||
- v0.dev vragen om complexe backend logica → niet zijn sterke punt
|
||||
- OpenCode vragen om design inspiratie → kan geen images maken
|
||||
```typescript
|
||||
import { useState } from 'react';
|
||||
|
||||
**❌ Heen en weer kopiëren zonder begrip:**
|
||||
- Kopieer niet blind code van ChatGPT naar je project
|
||||
- Begrijp eerst WAT de code doet
|
||||
// Type inference werkt vaak
|
||||
const [count, setCount] = useState(0); // number
|
||||
|
||||
**❌ Dezelfde prompt in elke tool:**
|
||||
- Pas je prompt aan per tool
|
||||
- v0.dev wil visuele beschrijvingen
|
||||
- OpenCode wil project-specifieke context
|
||||
// Explicit type voor complexe data
|
||||
interface User {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
const [user, setUser] = useState<User | null>(null);
|
||||
|
||||
// Array van objecten
|
||||
const [users, setUsers] = useState<User[]>([]);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Je Eigen Workflow Documenteren
|
||||
### Generics Basics
|
||||
|
||||
Maak een `docs/WORKFLOW.md` in je project:
|
||||
Generics maken code herbruikbaar:
|
||||
|
||||
```markdown
|
||||
# Mijn AI Workflow
|
||||
```typescript
|
||||
// Array is een generic type
|
||||
const numbers: Array<number> = [1, 2, 3];
|
||||
const names: Array<string> = ["Tim", "Anna"];
|
||||
|
||||
## Planning Fase
|
||||
- Tool: ChatGPT
|
||||
- Wat: Feature breakdown, technische beslissingen
|
||||
- Template prompt: "Ik wil [feature]. Wat zijn de stappen?"
|
||||
// Promise is een generic type
|
||||
async function fetchUser(): Promise<User> {
|
||||
const response = await fetch('/api/user');
|
||||
return response.json();
|
||||
}
|
||||
|
||||
## UI Design Fase
|
||||
- Tool: v0.dev
|
||||
- Wat: Component prototypes
|
||||
- Template prompt: "Modern [component] with [requirements]"
|
||||
// Je kunt ook eigen generics maken
|
||||
function firstElement<T>(arr: T[]): T | undefined {
|
||||
return arr[0];
|
||||
}
|
||||
|
||||
## Implementation Fase
|
||||
- Tool: OpenCode
|
||||
- Wat: Code schrijven en integreren
|
||||
- Template prompt: "Maak [component] in [locatie] met [requirements]"
|
||||
const first = firstElement([1, 2, 3]); // type: number | undefined
|
||||
```
|
||||
|
||||
## Debugging
|
||||
- Tool: OpenCode (eerst), Claude (als het complex is)
|
||||
- Wat: Errors oplossen
|
||||
- Template prompt: "Ik krijg deze error: [error]. Dit is mijn code: [code]"
|
||||
---
|
||||
|
||||
### Veelvoorkomende Errors
|
||||
|
||||
**Error 1: Type 'X' is not assignable to type 'Y'**
|
||||
```typescript
|
||||
let name: string = 42; // Error!
|
||||
// Fix: gebruik correct type
|
||||
let name: string = "Tim";
|
||||
```
|
||||
|
||||
**Error 2: Property 'X' does not exist on type 'Y'**
|
||||
```typescript
|
||||
interface User { name: string; }
|
||||
const user: User = { name: "Tim" };
|
||||
console.log(user.age); // Error! 'age' bestaat niet
|
||||
// Fix: voeg property toe aan interface
|
||||
```
|
||||
|
||||
**Error 3: Object is possibly 'undefined'**
|
||||
```typescript
|
||||
const users: User[] = [];
|
||||
console.log(users[0].name); // Error! users[0] kan undefined zijn
|
||||
// Fix: check eerst
|
||||
if (users[0]) {
|
||||
console.log(users[0].name);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### JS naar TS Omzetten
|
||||
|
||||
**Stap 1:** Rename `.js` naar `.tsx` (voor React) of `.ts`
|
||||
|
||||
**Stap 2:** Fix de rode errors - meestal:
|
||||
- Voeg types toe aan function parameters
|
||||
- Maak interfaces voor objecten
|
||||
- Handle nullable values
|
||||
|
||||
**Voorbeeld:**
|
||||
|
||||
```javascript
|
||||
// Voorheen (JavaScript)
|
||||
function UserCard({ user }) {
|
||||
return <div>{user.name}</div>;
|
||||
}
|
||||
```
|
||||
|
||||
```typescript
|
||||
// Nu (TypeScript)
|
||||
interface User {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface UserCardProps {
|
||||
user: User;
|
||||
}
|
||||
|
||||
function UserCard({ user }: UserCardProps) {
|
||||
return <div>{user.name}</div>;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tools
|
||||
- ChatGPT
|
||||
- Claude
|
||||
- v0.dev
|
||||
- OpenCode/WebStorm
|
||||
- TypeScript (via Next.js)
|
||||
- React
|
||||
|
||||
---
|
||||
|
||||
## Lesopdracht (2 uur)
|
||||
|
||||
### Tool Comparison Challenge
|
||||
### TypeScript Hands-on
|
||||
|
||||
**Deel 1: Dezelfde Taak, Drie Tools (1 uur)**
|
||||
**Deel 1: JS naar TS Omzetten (45 min)**
|
||||
|
||||
Bouw een "Contact Form" component met alle drie de tools:
|
||||
Gegeven JavaScript component:
|
||||
|
||||
1. **ChatGPT (20 min)**
|
||||
- Vraag om code + uitleg
|
||||
- Noteer: hoe lang duurde het, kwaliteit output, wat miste?
|
||||
```javascript
|
||||
function ProductCard({ product, onAddToCart }) {
|
||||
return (
|
||||
<div className="p-4 border rounded">
|
||||
<h2>{product.name}</h2>
|
||||
<p>${product.price}</p>
|
||||
{product.description && <p>{product.description}</p>}
|
||||
<button onClick={() => onAddToCart(product.id)}>
|
||||
Add to Cart
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
2. **v0.dev (20 min)**
|
||||
- Genereer visueel prototype
|
||||
- Noteer: hoe snel, hoe mooi, hoe aanpasbaar?
|
||||
Zet dit om naar TypeScript:
|
||||
1. Maak `Product` interface
|
||||
2. Maak `ProductCardProps` interface
|
||||
3. Type de component
|
||||
4. Fix alle TypeScript errors
|
||||
|
||||
3. **OpenCode (20 min)**
|
||||
- Integreer in bestaand project
|
||||
- Noteer: hoe goed past het, hoeveel aanpassing nodig?
|
||||
**Deel 2: Interfaces Schrijven (30 min)**
|
||||
|
||||
**Deel 2: Analyse (30 min)**
|
||||
Maak interfaces voor:
|
||||
|
||||
Vul dit schema in:
|
||||
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)
|
||||
|
||||
| Aspect | ChatGPT | v0.dev | OpenCode |
|
||||
|--------|---------|--------|----------|
|
||||
| Tijd tot werkend component | | | |
|
||||
| Kwaliteit code | | | |
|
||||
| Visueel design | | | |
|
||||
| Past in project | | | |
|
||||
| Hoeveel aanpassing nodig | | | |
|
||||
| Totaalscore (1-10) | | | |
|
||||
**Deel 3: React Component met Types (45 min)**
|
||||
|
||||
**Deel 3: Workflow Documentatie (30 min)**
|
||||
Bouw een `UserList` component:
|
||||
- Props: users array, onSelectUser callback
|
||||
- State: selectedUserId (number of null)
|
||||
- Toon lijst van users, highlight geselecteerde
|
||||
|
||||
- Maak `docs/WORKFLOW.md` in je project
|
||||
- Documenteer je ideale workflow per taaktype
|
||||
- Inclusief template prompts voor elke tool
|
||||
Alle types moeten correct zijn. Geen `any` gebruiken!
|
||||
|
||||
### Deliverable
|
||||
- Screenshot van alle 3 contact forms
|
||||
- Ingevuld vergelijkingsschema
|
||||
- `docs/WORKFLOW.md` bestand
|
||||
- ProductCard.tsx met correcte types
|
||||
- types.ts met alle interfaces
|
||||
- UserList.tsx volledig getypt
|
||||
|
||||
---
|
||||
|
||||
## Huiswerk (2 uur)
|
||||
|
||||
### Bouw Je Tool Selection Cheat Sheet
|
||||
### TypeScript Verdieping
|
||||
|
||||
**Deel 1: Cheat Sheet Maken (1 uur)**
|
||||
**Deel 1: Drie Components Bouwen (1 uur)**
|
||||
|
||||
Maak een persoonlijke "Tool Selection Cheat Sheet" (1 pagina):
|
||||
Bouw volledig in TypeScript:
|
||||
|
||||
```markdown
|
||||
# Mijn AI Tool Cheat Sheet
|
||||
1. **SearchInput** component
|
||||
- Props: value, onChange, placeholder (optioneel)
|
||||
- Volledig getypt
|
||||
|
||||
## Wanneer gebruik ik wat?
|
||||
2. **DataTable** component
|
||||
- Generic: werkt met elk type data
|
||||
- Props: data array, columns config
|
||||
- Type-safe rendering
|
||||
|
||||
### ChatGPT
|
||||
- ✅ Gebruik voor: [jouw ervaring]
|
||||
- ❌ Niet voor: [jouw ervaring]
|
||||
- 💡 Beste prompt tip: [jouw tip]
|
||||
3. **Modal** component
|
||||
- Props: isOpen, onClose, title, children
|
||||
- Correct gebruik van React.ReactNode
|
||||
|
||||
### Claude
|
||||
- ✅ Gebruik voor: [jouw ervaring]
|
||||
- ❌ Niet voor: [jouw ervaring]
|
||||
- 💡 Beste prompt tip: [jouw tip]
|
||||
**Deel 2: Eindproject Interfaces (30 min)**
|
||||
|
||||
### v0.dev
|
||||
- ✅ Gebruik voor: [jouw ervaring]
|
||||
- ❌ Niet voor: [jouw ervaring]
|
||||
- 💡 Beste prompt tip: [jouw tip]
|
||||
Bedenk de data structuur voor je eindproject:
|
||||
- Welke entiteiten heb je? (users, posts, products, etc.)
|
||||
- Maak interface voor elke entiteit
|
||||
- Documenteer relaties tussen entiteiten
|
||||
|
||||
### OpenCode
|
||||
- ✅ Gebruik voor: [jouw ervaring]
|
||||
- ❌ Niet voor: [jouw ervaring]
|
||||
- 💡 Beste prompt tip: [jouw tip]
|
||||
**Deel 3: Cheat Sheet (30 min)**
|
||||
|
||||
## Mijn Favoriete Combinaties
|
||||
1. [Workflow 1]
|
||||
2. [Workflow 2]
|
||||
```
|
||||
|
||||
**Deel 2: Testen op Nieuwe Taken (45 min)**
|
||||
|
||||
Test je cheat sheet op 2 nieuwe taken:
|
||||
1. Bouw een "Testimonial Card" component
|
||||
2. Voeg een "Dark Mode Toggle" toe
|
||||
|
||||
Per taak:
|
||||
- Kies tools op basis van je cheat sheet
|
||||
- Voer uit en noteer resultaat
|
||||
- Update cheat sheet indien nodig
|
||||
|
||||
**Deel 3: Reflectie (15 min)**
|
||||
|
||||
Schrijf korte reflectie (400 woorden):
|
||||
- Welke tool is jouw favoriet en waarom?
|
||||
- Wanneer combineer je tools?
|
||||
- Wat ga je anders doen na deze les?
|
||||
Maak persoonlijke TypeScript cheat sheet:
|
||||
- Meest gebruikte types
|
||||
- Interface vs Type wanneer
|
||||
- Common patterns met React
|
||||
- Hoe je errors oplost
|
||||
|
||||
### Deliverable
|
||||
- Tool Selection Cheat Sheet (1 pagina)
|
||||
- 2 gebouwde components (Testimonial Card, Dark Mode Toggle)
|
||||
- Reflectie (400 woorden)
|
||||
- 3 TypeScript components
|
||||
- types/index.ts met eindproject interfaces
|
||||
- TypeScript cheat sheet (1 pagina)
|
||||
|
||||
---
|
||||
|
||||
## Leerdoelen
|
||||
Na deze les kan de student:
|
||||
- De sterke en zwakke punten van elke AI tool benoemen
|
||||
- De juiste tool kiezen voor een specifieke taak
|
||||
- Meerdere tools combineren in een effectieve workflow
|
||||
- Een persoonlijke workflow documenteren
|
||||
- Template prompts schrijven per tool
|
||||
- Kritisch evalueren welke tool wanneer het beste werkt
|
||||
- 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
|
||||
|
||||
Reference in New Issue
Block a user