JavaScript/TypeScript Crash Course για Developers
Τύποι, narrowing χωρίς casts, async/await και ένα Server Action sketch.
Χωρίς πρόσφατο έλεγχο περιεχομένου. Οι εντολές και τα παραδείγματα ενδέχεται να έχουν αλλάξει από τη δημοσίευση.
Τύποι, narrowing χωρίς casts, async/await και ένα Server Action sketch.
JavaScript/TypeScript Crash Course για Developers
Το σύγχρονο οικοσύστημα του Next.js 16 και του Node.js απαιτεί βαθιά κατανόηση του αυστηρού TypeScript (Strict Mode). Αυτός ο οδηγός συνοψίζει τα πιο κρίσιμα μοτίβα τύπων και ασύγχρονου προγραμματισμού που χρειάζεστε στην καθημερινή πρακτική.
1. Discriminated Unions: Το Απόλυτο Pattern Κατάστασης
Αντί για πολλαπλά optional πεδία, χρησιμοποιήστε ένα κοινό discriminant πεδίο (status ή success):
typescripttype ActionResult<T> = | { success: true; data: T } | { success: false; error: string; code: 'UNAUTHORIZED' | 'VALIDATION_ERROR' | 'SERVER_ERROR' }; function handleResult(res: ActionResult<{ user_id: string }>) { if (res.success) { // Το TypeScript ξέρει με βεβαιότητα ότι υπάρχει το data! console.log("Success ID:", res.data.user_id); } else { // Εδώ υπάρχει εγγυημένα το error και το code console.error("Failed with code:", res.code, res.error); } }
2. Type Narrowing χωρίς επικίνδυνα as Casts
Η χρήση του as SomeType (Type Assertion) απενεργοποιεί τον compiler και κρύβει runtime bugs. Αντ' αυτού, στενέψτε τους τύπους μέσω Type Guards:
typescript// ❌ ΚΑΚΗ ΠΡΑΚΤΙΚΗ: Παράκαμψη του compiler // const email = (user as any).email; // ✅ ΒΕΛΤΙΣΤΟ: User-defined Type Guard interface AuthenticatedUser { id: string; email: string; tier: 'free' | 'pro'; } function isAuthenticatedUser(user: unknown): user is AuthenticatedUser { return ( typeof user === 'object' && user !== null && 'id' in user && 'email' in user && typeof (user as Record<string, unknown>).email === 'string' ); }
3. Ασύγχρονος Προγραμματισμός με async / await
typescriptasync function fetchCourseData(slug: string) { try { const res = await fetch(`https://api.roboschool.dev/courses/${encodeURIComponent(slug)}`, { next: { revalidate: 3600 }, }); if (!res.ok) { if (res.status === 404) return null; throw new Error(`Failed to fetch course: ${res.status} ${res.statusText}`); } return await res.json(); } catch (err) { // Σωστό error narrowing σε catch blocks const message = err instanceof Error ? err.message : 'Unknown network failure'; console.error('[CourseFetchError]', message); throw new Error(message); } }
4. Production Next.js 16 Server Action Pattern
Ένα ασφαλές Server Action επικυρώνει τα δεδομένα εισόδου με Zod και επιστρέφει αυστηρά typed αποτελέσματα:
typescript// src/actions/update-profile.ts 'use server' import { z } from 'zod' const ProfileSchema = z.object({ fullName: z.string().trim().min(2, 'Το ονοματεπώνυμο απαιτεί τουλάχιστον 2 χαρακτήρες').max(100), }) export type ActionState = { success?: boolean; errors?: { fullName?: string[] }; message?: string; } export async function updateProfileAction(prevState: ActionState, formData: FormData): Promise<ActionState> { const parsed = ProfileSchema.safeParse({ fullName: formData.get('fullName'), }); if (!parsed.success) { return { success: false, errors: parsed.error.flatten().fieldErrors, }; } // Εκτέλεση ασφαλούς mutation στη βάση... return { success: true, message: 'Το προφίλ ενημερώθηκε επιτυχώς!' }; }