ป้ายกำกับ: Vulnerability Auditing

TypeScript Guide: เจาะลึกการใช้งาน Union Types ใน Argument ของฟังก์ชันTypeScript Guide: เจาะลึกการใช้งาน Union Types ใน Argument ของฟังก์ชัน

ในโลกของการพัฒนาซอฟต์แวร์ที่ซับซ้อน การจัดการกับข้อมูลที่มีแหล่งที่มาหลากหลายเป็นเรื่องปกติ โดยเฉพาะอย่างยิ่งเมื่อระบบต้องเชื่อมต่อกับฐานข้อมูลอย่าง PostgreSQL ซึ่งข้อมูลที่ดึงมาอาจมีรูปแบบและประเภทที่ไม่ตายตัว TypeScript จึงเข้ามามีบทบาทสำคัญในการสร้างความมั่นใจในความถูกต้องของโค้ด (Type Safety) และหนึ่งในคุณสมบัติที่ทรงพลังที่สุดคือ Union Types

Union Types อนุญาตให้เรากำหนดว่าตัวแปรหรือพารามิเตอร์ของฟังก์ชันสามารถเป็นได้มากกว่าหนึ่งประเภทข้อมูล (เช่น เป็นได้ทั้ง string หรือ number) บทความนี้จะเจาะลึกว่าเราจะใช้ Union Types เพื่อจำกัดชนิดข้อมูลที่เป็นไปได้สำหรับ Arguments ของฟังก์ชันได้อย่างไร เพื่อให้โค้ดของเรามีความยืดหยุ่นแต่ยังคงความปลอดภัยสูงสุด

💡 ทำไมต้องใช้ Union Types กับ Function Arguments?

เมื่อระบบของเราต้องรับค่าอินพุตที่มาจากหลายส่วน เช่น ID ที่มาจาก HTTP Header (มักเป็น String) และ ID ที่มาจาก Primary Key ของฐานข้อมูล (มักเป็น Integer) การใช้ Argument Type เดียวจะทำให้ระบบขาดความยืดหยุ่น แต่การปล่อยให้ไม่มีการตรวจสอบ Type เลยก็จะนำไปสู่ข้อผิดพลาดที่แก้ไขยากใน Runtime

Union Types เข้ามาแก้ปัญหานี้โดยการกำหนดขอบเขตที่ชัดเจนว่า Input นั้น ๆ สามารถเป็นได้แค่ประเภทใดบ้าง ทำให้เราสามารถเขียน Logic Handler ที่จัดการกับทุกกรณีที่เป็นไปได้ได้อย่างครบถ้วน

🛠️ การใช้งาน Union Types ในการจัดการข้อมูล PostgreSQL

สมมติว่าเรามีฟังก์ชันที่ใช้สำหรับค้นหา Record โดยใช้ ID ซึ่ง ID นี้อาจถูกส่งมาในรูปแบบ UUID (String) หรือเป็น Integer ID ที่ถูกแปลงมาจาก PostgreSQL โดยตรง การกำหนด Type ด้วย Union จะช่วยให้ TypeScript ทราบว่าต้องมีการตรวจสอบทั้งสองรูปแบบ:

SQL

// TypeScript Code Simulation (Function Signature) 
function getRecordById(id: string | number): any {
    // Logic: ต้องมีการตรวจสอบ type ภายในฟังก์ชัน
    if (typeof id === 'string') {
        // กรณีที่ ID เป็น String (เช่น UUID) 
        // ใช้สำหรับ Query ในรูปแบบ WHERE uuid = $1
        return `SELECT * FROM records WHERE uuid = '${id}'`;
    } else if (typeof id === 'number') {
        // กรณีที่ ID เป็น Number (เช่น INT) 
        // ใช้สำหรับ Query ในรูปแบบ WHERE id = $1
        return `SELECT * FROM records WHERE id = ${id}`; 
    }
    // ถ้าเป็นประเภทอื่น จะเกิด Error ใน Compile Time
    throw new Error("Invalid ID type provided.");
}

// ตัวอย่างการเรียกใช้:
const uuidId = 'a1b2c3d4-e5f6-7890-abcd-ef0123456789';
const intId = 123;

// การเรียกใช้ที่ถูกต้อง:
console.log(getRecordById(uuidId));
console.log(getRecordById(intId));

// การเรียกใช้ที่ผิดประเภท (TypeScript จะแจ้งเตือน): 
// getRecordById('abc'); // Type 'abc' is not assignable to parameter type 'string | number'.

✅ ข้อดีหลัก: ความปลอดภัยและความยืดหยุ่น (Safety & Flexibility)

  • Type Narrowing: เมื่อใช้ Union Type เราสามารถใช้คำสั่ง typeof หรือ instanceof ภายในฟังก์ชันเพื่อ ‘จำกัด’ Type ให้แคบลง ทำให้เรามั่นใจว่าโค้ดที่รันต่อไปจะทำงานกับ Type ที่ถูกต้องเสมอ
  • Robustness: ช่วยให้โค้ดของเราสามารถรับมือกับความหลากหลายของข้อมูลที่มาจากหลายแหล่ง (เช่น API Gateway หรือ ORM Layer) โดยไม่เกิดข้อผิดพลาดที่ไม่คาดคิด

🚀 บทสรุป

Union Types เป็นเครื่องมือที่ขาดไม่ได้สำหรับนักพัฒนาที่ทำงานกับระบบที่ซับซ้อนและมีการเชื่อมต่อกับฐานข้อมูลหลากหลายรูปแบบ การใช้มันอย่างถูกต้องไม่เพียงแต่เพิ่มความยืดหยุ่นในการรับค่า Argument เท่านั้น แต่ยังช่วยยกระดับความปลอดภัยของโค้ดให้ทัดเทียมกับการทำงานของระบบที่ต้องการความแม่นยำสูงอย่าง PostgreSQL อีกด้วย การทำความเข้าใจและประยุกต์ใช้ Union Types จะช่วยให้คุณเขียนโค้ดที่ทั้งยืดหยุ่นและแข็งแกร่งในเวลาเดียวกัน