Skip to content

Type Guards in TypeScript

Type Guards คือ เทคนิคที่ช่วยให้ TypeScript สามารถระบุประเภทของตัวแปรได้อย่างแม่นยำมากขึ้น ในขณะ runtime

typeof Type Guards

ใช้ typeof เพื่อตรวจสอบประเภทพื้นฐานของตัวแปร (string, number, boolean, symbol, undefined, object, function)

typescript
function padLeft(value: string, padding: string | number) {
  if (typeof padding === "number") {
    return Array(padding + 1).join(" ") + value; // ถ้า padding เป็น number ให้เพิ่มช่องว่าง
  }
  return padding + value; // ถ้าเป็น string จะต่อ string ตามปกติ
}

instanceof Type Guards

ใช้ instanceof เพื่อตรวจสอบว่า object เป็น instance ของ class หรือไม่

typescript
class Bird {
  fly() {
    console.log("flying");
  }
}

class Fish {
  swim() {
    console.log("swimming");
  }
}

function move(pet: Bird | Fish) {
  if (pet instanceof Bird) {
    pet.fly(); // TypeScript รู้ว่า pet เป็น Bird
  } else {
    pet.swim(); // TypeScript รู้ว่า pet เป็น Fish
  }
}

User-Defined Type Guards

สามารถสร้าง type guard ของตัวเองโดยใช้ฟังก์ชันที่คืนค่า type predicate

typescript
interface Cat {
  meow(): void;
}

interface Dog {
  bark(): void;
}

function isCat(pet: Cat | Dog): pet is Cat {
  return (pet as Cat).meow !== undefined; // ตรวจสอบว่ามี method meow หรือไม่
}

function petSound(pet: Cat | Dog) {
  if (isCat(pet)) {
    pet.meow(); // TypeScript รู้ว่า pet เป็น Cat
  } else {
    pet.bark(); // TypeScript รู้ว่า pet เป็น Dog
  }
}

in Operator Type Guards

ใช้ in operator เพื่อตรวจสอบว่ามี property ใน object หรือไม่

typescript
interface Square {
  kind: "square";
  size: number;
}

interface Rectangle {
  kind: "rectangle";
  width: number;
  height: number;
}

function area(shape: Square | Rectangle) {
  if ("size" in shape) {
    return shape.size * shape.size; // รู้ว่าเป็น Square
  } else {
    return shape.width * shape.height; // รู้ว่าเป็น Rectangle
  }
}

Comparison Table

Type Guardใช้กับตัวอย่าง
typeofPrimitive typestypeof x === "string"
instanceofClassesx instanceof Date
User-DefinedCustom typesisCat(x)
in operatorObjects"size" in shape

Code Group Example

ts
// Type guards with union types
function processValue(value: string | number) {
  if (typeof value === "string") {
    return value.toUpperCase(); // ทำงานกับ string
  } else {
    return value.toFixed(2); // ทำงานกับ number
  }
}
ts
// Type guards with discriminated unions
interface Success {
  type: "success";
  data: string;
}

interface Error {
  type: "error";
  message: string;
}

function handleResponse(response: Success | Error) {
  switch (response.type) {
    case "success":
      console.log(response.data); // รู้ว่าเป็น Success
      break;
    case "error":
      console.error(response.message); // รู้ว่าเป็น Error
      break;
  }
}