ใน TypeScript (TS) ตัวแปรเป็นเครื่องมือสำคัญในการจัดเก็บข้อมูล โดย TS เพิ่มความสามารถในการระบุ ชนิดข้อมูล (Type Annotation) ให้กับตัวแปร เพื่อให้โค้ดมีความปลอดภัยและสามารถตรวจจับข้อผิดพลาดได้ตั้งแต่ขั้นตอนการเขียน
1. การประกาศตัวแปร (Variable Declaration)
TypeScript ใช้รูปแบบการประกาศตัวแปรเดียวกับ JavaScript โดยมี 3 คีย์เวิร์ดหลัก คือ var, let, และ const
| คีย์เวิร์ด | ขอบเขต (Scope) | การกำหนดค่าใหม่ (Reassignment) |
| var | Function Scope | ทำได้ |
| let | Block Scope (แนะนำ) | ทำได้ |
| const | Block Scope (แนะนำ) | ทำไม่ได้ (ค่าคงที่) |
ตัวอย่าง:
let name1: string; // การประกาศแบบไม่กำหนดค่าเริ่มต้น
let name2: string = 'Ebiwayo'; // ประกาศพร้อมกำหนดค่า (Type Annotation)
// ตัวแปรที่ประกาศโดยไม่กำหนดค่าเริ่มต้นจะมีค่าเป็น undefined
let price; // TypeScript จะอนุมาน (Inference) ว่าเป็นชนิด any
if (true) {
let message = 'Hello'; // ถูกจำกัดขอบเขตในบล็อก if นี้เท่านั้น
}
// console.log(message); // จะเกิด Error: Cannot find name 'message'
ข้อควรจำใน TypeScript:
ตัวแปรที่ไม่ได้กำหนดค่าจะมีค่าเริ่มต้นเป็น undefined (ไม่ใช่
nullเหมือน Dart เว้นแต่เราจะกำหนดเอง)หากเราประกาศตัวแปรและกำหนดค่าเริ่มต้น TS จะใช้ Type Inference ในการอนุมานชนิดข้อมูลโดยอัตโนมัติ (เช่น
let age = 25;จะถูกอนุมานเป็นnumber)
2. การกำหนดชนิดข้อมูลแบบชัดเจน (Type Annotations)
หัวใจของ TypeScript คือการใช้ : ตามหลังชื่อตัวแปรเพื่อระบุชนิดข้อมูลอย่างชัดเจน (Type Annotation)
| ชนิดข้อมูล (Type) | คำอธิบาย | ตัวอย่าง |
| string | ข้อความ (ใช้ตัวพิมพ์เล็ก) |
let name: string = 'Ebiwayo'; |
| number | ตัวเลขทั้งหมด (จำนวนเต็ม/ทศนิยม) |
let age: number = 25; |
| boolean |
ค่าตรรกะ (true หรือ false) |
let graduated: boolean = true; |
| any |
ยอมรับได้ทุกชนิด (คล้าย dynamic ใน Dart) |
let data: any = 'mixed value'; |
| unknown |
เหมือน any แต่ปลอดภัยกว่า (ต้องตรวจสอบชนิดข้อมูลก่อนใช้) |
let unknownData: unknown = 10; |
ตัวอย่างการระบุชนิดข้อมูล:
let name: string = 'Ebiwayo'; let age: number = 25; let weight: number = 48.5; // ทั้งจำนวนเต็มและทศนิยมใช้ number // ถ้าค่าที่กำหนดไม่ตรงตามชนิดที่ประกาศ จะเกิด Error ตั้งแต่ตอน Compile // name = 123; // Error: Type 'number' is not assignable to type 'string'.
3. ชนิดข้อมูลเพิ่มเติมที่สำคัญ (Key TypeScript Types)
| ชนิดข้อมูล | คำอธิบาย | ตัวอย่าง |
| Array |
กลุ่มข้อมูลชนิดเดียวกัน (คล้าย List ใน Dart) |
let hobby: string[] = ['Reading', 'Jogging']; |
| Tuple | Array ที่มีขนาดและชนิดข้อมูลของแต่ละตำแหน่งที่ตายตัว |
let position: [number, string] = [1, 'first']; |
| Union | ตัวแปรสามารถเป็นได้หลายชนิดข้อมูลที่กำหนดไว้ | `let id: string |
| Enum | กลุ่มของค่าคงที่ที่มีชื่อเป็นมิตร |
enum Direction { Up, Down, Left, Right } |
| Object/Map |
คล้าย Map ใน Dart, ใช้ Interface หรือ Type Alias |
let person: { city: string, country: string } = { ... }; |
4. ตัวแปรคงที่ (Immutable Variables)
ในการกำหนดตัวแปรที่เราไม่ต้องการเปลี่ยนแปลงค่า เราใช้ const สำหรับตัวแปร และ readonly สำหรับคุณสมบัติ (Property) ภายใน class หรือ interface
การใช้งาน const
const ถูกใช้เพื่อป้องกันการ Reassign (กำหนดค่าใหม่) ให้กับตัวแปรหลักหลังจากการประกาศครั้งแรก
const PI: number = 3.14159; // PI = 3.14; // Error: Cannot assign to 'PI' because it is a constant. const list = [1, 2, 3]; // list = [4, 5, 6]; // Error: เปลี่ยนค่าตัวแปรหลักไม่ได้ list.push(4); // แต่ยังสามารถเปลี่ยนแปลงข้อมูลภายใน Array ได้ (Mutability)
การใช้งาน readonly ในคลาส
ใน TypeScript จะใช้คีย์เวิร์ด readonly ภายในคลาส เพื่อป้องกันการแก้ไขค่าของ Property หลังจากที่ Object ถูกสร้างขึ้น
class Shape {
readonly name: string;
static readonly PI: number = 3.14; // static readonly สำหรับค่าคงที่ใน Class
constructor(name: string) {
this.name = name;
}
}
let circle = new Shape('Circle');
// circle.name = 'Square'; // Error: 'name' is readonly.
ข้อสังเกต: ใน TypeScript ไม่มีการจำแนกหน่วยความจำที่ซับซ้อนระหว่าง
finalและconstเหมือน Dart แนวคิดหลักคือการใช้ const สำหรับความไม่เปลี่ยนแปลงของตัวแปรในระดับ Block Scope
5. ข้อมูลประเภทคอลเลกชัน (Collections: Array, Set, Map)
TypeScript ใช้ Generics ในการกำหนดชนิดข้อมูลของสมาชิกในคอลเลกชัน ซึ่งช่วยเสริมความปลอดภัยของชนิดข้อมูล
Arrays (Lists)
TypeScript ใช้ Array (วงเล็บเหลี่ยม []) ในการจัดกลุ่มข้อมูล โดยมีการระบุชนิดข้อมูลของสมาชิกอย่างชัดเจน
// รูปแบบที่แนะนำ: ชนิดข้อมูล[] let hobby: string[] = ['Reading', 'Jogging', 'Shopping']; // รูปแบบ Generics (คล้าย Dart): Array<T> let numbers: Array<number> = [1, 2, 3]; // hobby.push(10); // Error: Argument of type 'number' is not assignable to parameter of type 'string'.
Maps (Objects/Dictionaries)
ใน TypeScript เราสามารถกำหนดโครงสร้างของ Object (คล้าย Map ใน Dart) ได้หลายวิธี โดยวิธีที่ง่ายที่สุดคือการใช้ Literal Object Type หรือใช้ Interface/Type Alias (ซึ่งเป็นหัวข้อในเชิงลึก)
// Literal Object Type
let address: { [key: string]: string | string[] } = {
'city': ['Bangkok', 'Nonthaburi'], // key เป็น string, value เป็น string[]
'country': 'Thailand' // key เป็น string, value เป็น string
};
console.log(address['country']); // การเข้าถึงข้อมูลด้วย Key
// การใช้ Map Class (สำหรับ Key ที่ซับซ้อนกว่า string)
let userAges: Map<string, number> = new Map();
userAges.set('Ebiwayo', 24);
console.log(userAges.get('Ebiwayo')); // 24