🛑 1. The Nightmare: "undefined is not a function"
ใครที่เคยเขียน JavaScript แบบเดิมคงรู้จักความเจ็บปวดนี้ดี แอปพังหน้างานเพราะข้อมูลที่ได้รับจาก API ไม่เป็นไปตามที่คิดไว้:
- "นึกว่าส่ง Array มา แต่ความจริงส่ง null"
- "นึกว่า id เป็นตัวเลข แต่ความจริงเป็น String"
Senior Solution: ในโลกของมืออาชีพ เราจะไม่ "เดา" ครับ เราจะใช้ TypeScript และ Zod เพื่อสร้างเกราะคุ้มกันให้โค้ดของเราแบบทุกช่วงเวลา (Runtime & Compile time)
💡 2. Real-Life Analogy: การก่อสร้างสะพานระหว่างเกาะ
- JavaScript (No Types): เหมือนการสร้างสะพานโดยการโยนไม้กระดานไปข้างหน้าเรื่อยๆ โดยไม่วัดขนาด คุณอาจจะโชคดีข้ามไปได้ แต่ก็มีโอกาสสูงที่จะร่วงลงน้ำกลางทาง
- TypeScript (Static Types): เหมือนการวาดพิมพ์เขียวและวัดทุกชิ้นส่วนก่อนเริ่มสร้าง ถ้าไม้ขนาดไม่พอดีตั้งแต่เริ่มต้น คุณจะรู้ทันทีและแก้ไขได้ก่อนจะเกิดอันตราย
- Zod (Runtime Validation): เหมือนมี "ด่านตรวจ" ที่หัวสะพานเพื่อเช็กว่ารถที่วิ่งเข้ามาหนักเกินไปไหม หรือเป็นรถปลอมแปลงมาหรือเปล่าก่อนที่จะปล่อยให้วิ่งบนสะพานจริง
🚀 3. Execution Journey: 3 เลเยอร์ของความปลอดภัย (The Holy Trinity)
ในการพัฒนาแอปยุคใหม่ ผมมักจะใช้ 3 เลเยอร์นี้เสมอ:
🛠 Step-by-step:
- Zod at the Door (Input Validation): ทุกครั้งที่มีการรับข้อมูลจากภายนอก (API, Form) เราต้องใช้ Zod
parse()เพื่อยืนยันว่าข้อมูล "ถูกต้อง" 100% ก่อนจะเอาไปใช้งานต่อ - TypeScript as the Glue: ใช้ Interface และ Types เชื่อมโยงข้อมูลจาก Backend ส่งต่อไปยังทุก Component เพื่อให้ VS Code ช่วยเตือนเมื่อเราเผลอสะกดผิดหรือใช้ผิดประเภท
- Prisma/DB Schema: กำหนดโครงสร้างฐานข้อมูลให้สอดคล้องกับโค้ด เพื่อไม่ให้เกิดภาวะ "ข้อมูลไม่ตรงกัน" (Data Inconsistency) ทุกจุดต้องคุยทิศทางเดียวกันทั้งหมด
// ✅ การใช้ Zod เพื่อสร้าง Type อัตโนมัติ (Single Source of Truth)
import { z } from "zod";
const UserSchema = z.object({
id: z.string().uuid(),
username: z.string().min(3),
email: z.string().email(),
});
// ดึง Type ออกจาก Schema ได้ทันที ไม่ต้องเขียนซ้ำ!
type User = z.infer<typeof UserSchema>;
🪤 4. The Junior Trap: การใช้คำสั่งในตำนาน "as any"
จูเนียร์มักจะใช้ any เพื่อหนี Error ของ TypeScript:
- ปัญหา: การใส่
anyคือการปิดระบบความปลอดภัยทั้งหมดทิ้งไป โค้ดของคุณจะกลับไปน่ากลัวเหมือนเดิม และ Bug จะไปโผล่ที่หน้าผู้ใช้แทน - ✅ การแก้ไข: จงใช้เวลาแก้ Type Error ให้ผ่าน หรือถ้าจำเป็นจริงๆ ให้ใช้
unknownแล้วเช็กประเภทข้อมูลด้วยif(Type Guard) จะดีกว่าเป็นร้อยเท่าครับ
⚖️ 5. The Reliability Matrix: ความเร็ว vs ความมั่นใจ
| หัวข้อ | JavaScript (Vanilla) | TypeScript (Senior Mode) |
|---|---|---|
| ความเร็วในการเขียนครั้งแรก | 🚀 เร็วมาก | 🐢 ช้ากว่า (ต้องนิยาม Type) |
| การ Refactor โค้ด | 😱 ฝันร้าย (ไม่กล้าแก้เพราะกลัวจุดอื่นพัง) | ✅ มั่นใจ (แก้จุดเดียว Error จะพุ่งขึ้นมาทุกจุดที่ต้องตามแก้) |
| ความเข้าใจของทีม | ต้องรันโค้ดถึงจะรู้ว่าข้อมูลคืออะไร | ✅ อ่านโค้ดก็รู้ทันที (Self-documenting) |
| ความเสถียรของแอป | 🎲 แล้วแต่ดวง | 💎 สูงมาก (ลด Bug ได้มหาศาล) |
🎓 6. Senior Mindset Summary
การเป็น Senior ไม่ได้วัดกันที่ว่าคุณเขียนโค้ดได้ "ฉลาด" แค่ไหน แต่วัดกันที่ว่าคุณเขียนโค้ดได้ "คาดเดาได้ (Predictable)" แค่ไหนต่างหากครับ TypeScript อาจจะดูน่ารำคาญในช่วงแรก แต่เชื่อผมเถอะครับว่า "การเสียเวลา 5 นาทีแก้ Type วันนี้ ดีกว่าเสียเวลา 5 ชั่วโมงไล่หา Bug ตอนเที่ยงคืน" แน่นอนครับ!