ไทย

คู่มือฉบับสมบูรณ์เกี่ยวกับ TypeScript Interface และ Type สำรวจความแตกต่าง กรณีการใช้งาน และแนวทางปฏิบัติที่ดีที่สุดเพื่อสร้างแอปพลิเคชันที่บำรุงรักษาและขยายขนาดได้ทั่วโลก

TypeScript Interface vs Type: แนวทางปฏิบัติที่ดีที่สุดในการประกาศสำหรับนักพัฒนาระดับโลก

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

ทำความเข้าใจ TypeScript Interfaces

Interface ใน TypeScript เป็นวิธีที่มีประสิทธิภาพในการกำหนดข้อตกลง (contract) สำหรับอ็อบเจกต์ มันจะร่างรูปทรงของอ็อบเจกต์ โดยระบุคุณสมบัติ (properties) ที่ต้องมี ประเภทข้อมูลของมัน และเมธอด (methods) ที่ควรจะนำไปใช้ (implement) ซึ่งเป็นทางเลือก Interfaces ทำหน้าที่หลักในการอธิบายโครงสร้างของอ็อบเจกต์

ไวยากรณ์และตัวอย่างของ Interface

ไวยากรณ์สำหรับการกำหนด interface นั้นตรงไปตรงมา:


interface User {
  id: number;
  name: string;
  email: string;
  isActive: boolean;
}

const user: User = {
  id: 123,
  name: "Alice Smith",
  email: "alice.smith@example.com",
  isActive: true,
};

ในตัวอย่างนี้ User interface กำหนดโครงสร้างของอ็อบเจกต์ผู้ใช้ อ็อบเจกต์ใดๆ ที่ถูกกำหนดให้กับตัวแปร user จะต้องยึดตามโครงสร้างนี้ มิฉะนั้น TypeScript compiler จะแจ้งข้อผิดพลาด

คุณสมบัติหลักของ Interfaces

ตัวอย่างการรวมการประกาศ (Declaration Merging)


interface Window {
  title: string;
}

interface Window {
  height: number;
  width: number;
}

const myWindow: Window = {
  title: "My Application",
  height: 800,
  width: 600,
};

ในที่นี้ Window interface ถูกประกาศสองครั้ง TypeScript จะรวมการประกาศเหล่านี้เข้าด้วยกัน ทำให้เกิด interface ที่มีคุณสมบัติ title, height, และ width อย่างมีประสิทธิภาพ

สำรวจ TypeScript Types

Type ใน TypeScript เป็นวิธีการกำหนดรูปทรงของข้อมูล ซึ่งแตกต่างจาก interface ตรงที่ type มีความหลากหลายมากกว่าและสามารถแสดงโครงสร้างข้อมูลได้หลากหลายรูปแบบ รวมถึงประเภทข้อมูลพื้นฐาน (primitive types), unions, intersections, และ tuples

ไวยากรณ์และตัวอย่างของ Type

ไวยากรณ์สำหรับการกำหนด type alias เป็นดังนี้:


type Point = {
  x: number;
  y: number;
};

const origin: Point = {
  x: 0,
  y: 0,
};

ในตัวอย่างนี้ Point type กำหนดโครงสร้างของอ็อบเจกต์จุดที่มีพิกัด x และ y

คุณสมบัติหลักของ Types

ตัวอย่าง Union Type


type Result = {
  success: true;
  data: any;
} | {
  success: false;
  error: string;
};

const successResult: Result = {
  success: true,
  data: { message: "Operation successful!" },
};

const errorResult: Result = {
  success: false,
  error: "An error occurred.",
};

Result type เป็น union type ที่สามารถเป็นได้ทั้งผลลัพธ์ที่สำเร็จพร้อมข้อมูล หรือผลลัพธ์ที่ล้มเหลวพร้อมข้อความแสดงข้อผิดพลาด สิ่งนี้มีประโยชน์สำหรับการแสดงผลลัพธ์ของการดำเนินการที่อาจสำเร็จหรือล้มเหลว

ตัวอย่าง Intersection Type


type Person = {
  name: string;
  age: number;
};

type Employee = {
  employeeId: string;
  department: string;
};

type EmployeePerson = Person & Employee;

const employee: EmployeePerson = {
  name: "Bob Johnson",
  age: 35,
  employeeId: "EMP123",
  department: "Engineering",
};

EmployeePerson type เป็น intersection type ซึ่งรวมคุณสมบัติของทั้ง Person และ Employee เข้าด้วยกัน สิ่งนี้ช่วยให้คุณสร้างประเภทใหม่โดยการรวมประเภทที่มีอยู่เดิม

ความแตกต่างที่สำคัญ: Interface vs Type

แม้ว่าทั้ง interface และ type จะทำหน้าที่กำหนดโครงสร้างข้อมูลใน TypeScript เหมือนกัน แต่ก็มีความแตกต่างที่สำคัญซึ่งมีผลต่อการตัดสินใจว่าจะใช้อันไหนดีกว่ากัน:

  1. การรวมการประกาศ (Declaration Merging): Interface รองรับการรวมการประกาศ ในขณะที่ type ไม่รองรับ หากคุณต้องการขยายนิยามของประเภทข้ามไฟล์หรือโมดูลต่างๆ interface มักจะเป็นตัวเลือกที่ดีกว่า
  2. Union Types: Type สามารถแสดง union types ได้ ในขณะที่ interface ไม่สามารถกำหนด unions ได้โดยตรง หากคุณต้องการกำหนดประเภทที่สามารถเป็นหนึ่งในหลายประเภทที่แตกต่างกัน ให้ใช้ type alias
  3. Intersection Types: Type สามารถสร้าง intersection types โดยใช้ตัวดำเนินการ & ส่วน Interface สามารถขยาย (extends) interface อื่นๆ เพื่อให้ได้ผลลัพธ์ที่คล้ายกัน แต่ intersection types ให้ความยืดหยุ่นมากกว่า
  4. Primitive Types: Type สามารถแสดงประเภทข้อมูลพื้นฐานได้โดยตรง (string, number, boolean) ในขณะที่ interface ถูกออกแบบมาเพื่อกำหนดรูปทรงของอ็อบเจกต์เป็นหลัก
  5. ข้อความแสดงข้อผิดพลาด (Error Messages): นักพัฒนาบางคนพบว่า interface ให้ข้อความแสดงข้อผิดพลาดที่ชัดเจนกว่าเล็กน้อยเมื่อเทียบกับ type โดยเฉพาะอย่างยิ่งเมื่อต้องจัดการกับโครงสร้างประเภทที่ซับซ้อน

แนวทางปฏิบัติที่ดีที่สุด: การเลือกระหว่าง Interface และ Type

การเลือกระหว่าง interface และ type ขึ้นอยู่กับความต้องการเฉพาะของโครงการและความชอบส่วนตัวของคุณ ต่อไปนี้เป็นแนวทางทั่วไปที่ควรพิจารณา:

ตัวอย่างการใช้งานจริง: สถานการณ์ในแอปพลิเคชันระดับโลก

ลองพิจารณาตัวอย่างการใช้งานจริงบางส่วนเพื่อแสดงให้เห็นว่า interface และ type สามารถนำไปใช้ในแอปพลิเคชันระดับโลกได้อย่างไร:

1. การจัดการโปรไฟล์ผู้ใช้ (Internationalization)

สมมติว่าคุณกำลังสร้างระบบจัดการโปรไฟล์ผู้ใช้ที่รองรับหลายภาษา คุณสามารถใช้ interface เพื่อกำหนดโครงสร้างของโปรไฟล์ผู้ใช้และใช้ type เพื่อแสดงรหัสภาษาต่างๆ:


interface UserProfile {
  id: number;
  name: string;
  email: string;
  preferredLanguage: LanguageCode;
  address: Address;
}

interface Address {
    street: string;
    city: string;
    country: string;
    postalCode: string;
}

type LanguageCode = "en" | "fr" | "es" | "de" | "zh"; // ตัวอย่างรหัสภาษา

const userProfile: UserProfile = {
  id: 1,
  name: "John Doe",
  email: "john.doe@example.com",
  preferredLanguage: "en",
  address: { street: "123 Main St", city: "Anytown", country: "USA", postalCode: "12345" }
};

ในที่นี้ UserProfile interface กำหนดโครงสร้างของโปรไฟล์ผู้ใช้ รวมถึงภาษาที่ต้องการ LanguageCode type เป็น union type ที่แสดงถึงภาษาที่รองรับ ส่วน Address interface กำหนดรูปแบบที่อยู่ โดยสมมติว่าเป็นรูปแบบสากลทั่วไป

2. การแปลงสกุลเงิน (Globalization)

พิจารณาแอปพลิเคชันแปลงสกุลเงินที่ต้องจัดการกับสกุลเงินและอัตราแลกเปลี่ยนต่างๆ คุณสามารถใช้ interface เพื่อกำหนดโครงสร้างของอ็อบเจกต์สกุลเงินและใช้ type เพื่อแสดงรหัสสกุลเงิน:


interface Currency {
  code: CurrencyCode;
  name: string;
  symbol: string;
}

interface ExchangeRate {
  baseCurrency: CurrencyCode;
  targetCurrency: CurrencyCode;
  rate: number;
}


type CurrencyCode = "USD" | "EUR" | "GBP" | "JPY" | "CAD"; // ตัวอย่างรหัสสกุลเงิน

const usd: Currency = {
  code: "USD",
  name: "United States Dollar",
  symbol: "$",
};

const exchangeRate: ExchangeRate = {
  baseCurrency: "USD",
  targetCurrency: "EUR",
  rate: 0.85,
};

Currency interface กำหนดโครงสร้างของอ็อบเจกต์สกุลเงิน รวมถึงรหัส ชื่อ และสัญลักษณ์ CurrencyCode type เป็น union type ที่แสดงถึงรหัสสกุลเงินที่รองรับ และ ExchangeRate interface ใช้เพื่อแสดงอัตราแลกเปลี่ยนระหว่างสกุลเงินต่างๆ

3. การตรวจสอบข้อมูล (รูปแบบสากล)

เมื่อจัดการกับข้อมูลที่ผู้ใช้ป้อนเข้ามาจากประเทศต่างๆ สิ่งสำคัญคือต้องตรวจสอบข้อมูลตามรูปแบบสากลที่ถูกต้อง ตัวอย่างเช่น หมายเลขโทรศัพท์มีรูปแบบที่แตกต่างกันไปตามรหัสประเทศ เราสามารถใช้ type เพื่อแสดงความแตกต่างเหล่านี้ได้


type PhoneNumber = {
  countryCode: string;
  number: string;
  isValid: boolean; // เพิ่มค่าบูลีนเพื่อแสดงข้อมูลที่ถูกต้อง/ไม่ถูกต้อง
};

interface Contact {
   name: string;
   phoneNumber: PhoneNumber;
   email: string;
}


function validatePhoneNumber(phoneNumber: string, countryCode: string): PhoneNumber {
  // โลจิกการตรวจสอบความถูกต้องตาม countryCode (เช่น ใช้ไลบรารีอย่าง libphonenumber-js)
  // ... โค้ดสำหรับตรวจสอบหมายเลขอยู่ที่นี่
  const isValid = true; //ค่าสำรอง

  return { countryCode, number: phoneNumber, isValid };
}

const contact: Contact = {
    name: "Jane Doe",
    phoneNumber: validatePhoneNumber("555-123-4567", "US"), //ตัวอย่าง
    email: "jane.doe@email.com",
};


console.log(contact.phoneNumber.isValid); //แสดงผลการตรวจสอบ

สรุป: การใช้ TypeScript Declarations อย่างเชี่ยวชาญ

TypeScript Interfaces และ Types เป็นเครื่องมือที่มีประสิทธิภาพสำหรับการกำหนดโครงสร้างข้อมูลและปรับปรุงคุณภาพของโค้ด การทำความเข้าใจความแตกต่างและการนำไปใช้อย่างมีประสิทธิภาพเป็นสิ่งจำเป็นสำหรับการสร้างแอปพลิเคชันที่แข็งแกร่ง บำรุงรักษาง่าย และขยายขนาดได้ โดยการปฏิบัติตามแนวทางปฏิบัติที่ดีที่สุดที่ระบุไว้ในคู่มือนี้ คุณสามารถตัดสินใจได้อย่างมีข้อมูลว่าจะใช้ interface หรือ type เมื่อใด ซึ่งจะช่วยปรับปรุงขั้นตอนการพัฒนา TypeScript ของคุณและส่งผลต่อความสำเร็จของโครงการของคุณในที่สุด

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

TypeScript Interface vs Type: แนวทางปฏิบัติที่ดีที่สุดในการประกาศสำหรับนักพัฒนาระดับโลก | MLOG