หากใครที่ใช้งาน typescript อยู่น่าจะเคยเห็นวิธีการประกาศ type อยู่ 2 รูปแบบหลักๆ คือ แบบ interface
และแบบ type
(Aliases Type) ซึ่งทั้ง 2 ตัวนี้อาจทำให้หลายคนสับสนได้ว่าเราจะใช้อะไรดี ซึ่งผมก็เป็นเหมือนกัน เลยถือโอกาศเขียนบนความไว้กันงง
ทำความรู้จักกันก่อน
เริ่มจากมาทำความรู้จักการประกาศ type ทั้ง 2 แบบก่อน
Interface
interface
จะเป็นตัวกำหนดว่า Object หรือ Class นั้นๆ จะมีหน้าตาอย่างไรบ้าง ถ้าใครรู้จัก OOP อยู่แล้ว ก็น่าจะคุ้นชินกับชื่อนี้ มันทำหน้าที่คล้ายๆ กันเลย แต่อาจจะมีการทำงานบางอย่างที่แตกต่างกันบ้าง (อาจจะเก็บไว้เขียนใน blog ต่อๆ ไป)
โดยเราสามารถการประกาศ interface ได้ดังนี้:
interface Person {
name: string;
age: number;
gender?: string; // Optional property
}
const person: Person = { name: 'John', age: 30 };
const person2: Person = { name: 'Sara', age: 25, gender: 'Women' };
การประกาศ Type ด้วย Interface
รูปแบบการใช้งาน interface
:
- Declaration Merging
interface Car {
brand: string;
}
interface Car {
model: string;
}
const myCar: Car = {
brand: 'Toyota',
model: 'Camry',
};
การประกาศ Type ซ้ำ
- Extending Interfaces
interface Shape {
color: string;
}
interface Square extends Shape {
sideLength: number;
}
สืบทอดคุณสมบัติจาก interface
อื่น
- Implements Keyword
interface Clock {
currentTime: Date;
setTime(d: Date): void;
}
class MyClock implements Clock {
currentTime: Date = new Date();
setTime(d: Date): void {
this.currentTime = d;
}
}
การใช้คีย์เวิร์ด implements
เพื่อบังคับให้ class ปฏิบัติตามโครงสร้างของ interface
- Readonly Properties
interface Point {
readonly x: number;
readonly y: number;
}
สามารถทำให้ property เป็น readonly
ได้
- Function Types
interface Calculate {
(x: number, y: number): number;
}
ใช้ interface
สำหรับกำหนดรูปแบบของฟังก์ชัน
Type
type aliases
หรือ เรียกอีกชื่อว่า type
เป็นเครื่องมือที่ช่วยในการสร้างชื่อใหม่สำหรับชนิดของข้อมูลที่มีอยู่แล้ว โดย type
สามารถทำ Union Types, Intersection Types, และ Mapped Types ได้
โดยเราสามารถการประกาศ type ได้ดังนี้:
type Age = number;
type Person = {
name: string;
age: Age;
};
const myAge: Age = 25;
const person: Person = { name: 'John', age: myAge };
รูปแบบการใช้งาน type
:
- Union Types
type Status = 'Pending' | 'Approved' | 'Rejected';
const currentStatus: Status = 'Approved';
การสร้าง Union Types
- Intersection Types
type Car = {
brand: string;
};
type ElectricCar = {
batteryLife: number;
} & Car;
const myCar: ElectricCar = {
brand: 'Tesla',
batteryLife: 300,
};
การสร้าง Intersection Types
- Declaration Merging (การประกาศซ้ำ)
type Person = { name: string };
type Person = { age: number }; // Declaration merging
การประกาศซ้ำ (declaration merging)
- Mapped Types:
type Flags = {
option1: boolean;
option2: boolean;
};
type FlagKeys = keyof Flags; // Mapped Type
การสร้างสร้าง Mapped Types
ความแตกต่างระหว่าง Interface กับ Type
ทั้ง type
และ interface
มีหน้าที่ทำงานที่คล้ายกัน แต่จะมีความแตกต่างกันอยู่บ้าง ขึ้นอยู่กับเราและทีมของเราเลยว่าอยากจะใช้งานแบบไหน หรือต้องการความสามารถอะไรจาก 2 ตัวนี้ เช่น
- ถ้าคุณต้องการการใช้
extends
หรือimplements
ในการสร้างสิ่งที่สืบทอด, หรือต้องการมีการประกาศซ้ำกัน,interface
อาจเป็นตัวเลือกที่ดี - ถ้าคุณต้องการใช้ Union, Intersection Types, หรือ Mapped Types,
type
อาจเป็นตัวเลือกที่ดี
Reference
https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#type-aliases