Skip to content
Grok

let username: string = "john"; username = 123; // Type Error: Cannot assign number to string

ประโยชน์ของ Static Typing:

  • จับข้อผิดพลาดตั้งแต่ยังไม่รันโปรแกรม
  • ช่วยให้ IDE แนะนำการใช้งานได้ถูกต้อง
  • ทำให้โค้ดอ่านง่ายขึ้น

Type Inference (การอนุมาน type)

เคล็ดลับ

ควรใช้ type inference เมื่อค่าเริ่มต้นชัดเจน แต่ควรระบุ type ชัดเจนเมื่อรับค่าจาก API หรือเมื่อต้องการความชัดเจน

TypeScript สามารถเดา type ได้โดยอัตโนมัติจากค่าที่กำหนด

ts
let 
message
= "Hello"; // TypeScript รู้ว่าเป็น string
let
count
= 10; // รู้ว่าเป็น number

Structural Typing (ระบบ type แบบโครงสร้าง)

ข้อควรระวัง

Object ที่มี property มากกว่าที่ interface กำหนดจะใช้งานได้ แต่ถ้ามี property น้อยกว่าจะเกิด error ทันที

ตรวจสอบความเข้ากันได้ของ type จากโครงสร้าง ไม่ใช่จากชื่อ type

ts
interface Product {
  
id
: number;
name
: string;
price
: number;
} function
displayProductInfo
(
product
: Product) {
console
.
log
(`${
product
.
name
}: $${
product
.
price
}`);
} // ตัวอย่างที่ 1: ใช้งานได้ตามปกติ const
laptop
= {
id
: 1,
name
: "MacBook Pro",
price
: 1999,
};
displayProductInfo
(
laptop
); // ทำงานได้ปกติ
// ตัวอย่างที่ 2: เกิด error เพราะขาด property ที่จำเป็น const
invalidProduct
= {
id
: 2,
name
: "iPhone",
}; // @ts-expect-error: Argument of type '{ id: number; name: string; }' is not assignable to parameter of type 'Product'.
displayProductInfo
(
invalidProduct
);
// ตัวอย่างที่ 3: เกิด error เมื่อพยายามใช้ object literal โดยตรง // @ts-expect-error: Argument of type '{ id: number; name: string; }' is not assignable to parameter of type 'Product'.
displayProductInfo
({
id
: 3,
name
: "iPad",
});

Type Checking (การตรวจสอบ type)

วิธีการตรวจสอบรูปแบบการใช้งานตัวอย่างการใช้
Type Predicatesfunction isType(value): value is Typefunction isString(value: unknown): value is string
typeof operatortypeof value === "type"if (typeof x === "string")

Type Guards (การป้องกัน type)

Type Guardวิธีใช้ตัวอย่างการใช้ใช้กับ
instanceofตรวจสอบ instance ของ classif (error instanceof Error)Class
in operatorตรวจสอบว่ามี property ใน object หรือไม่if ("id" in user)Object types
Custom Type Guardสร้างฟังก์ชันตรวจสอบ type เองfunction isFish(pet: Fish | Bird): pet is Fishทุก type
Equality Narrowingใช้การเปรียบเทียบค่าif (x === null)ทุก type
Discriminated Unionใช้ property ร่วมเพื่อแยก typeif (shape.kind === "circle")Union types

Type Casting (การแปลง type)

วิธีการรูปแบบ syntaxตัวอย่างการใช้
as syntaxvalue as TargetType(input as string).toUpperCase()
angle-bracket syntax<TargetType>value<string>input.toUpperCase()

Type Assertion (การยืนยัน type)

เทคนิคการบอก TypeScript ว่าเรารู้ type ของค่าที่แน่นอน (ใช้เมื่อเรารู้ว่า type จริงคืออะไร แต่ TypeScript ไม่สามารถอนุมานได้)

รูปแบบคำอธิบายตัวอย่างการใช้งาน
as syntaxรูปแบบมาตรฐานที่แนะนำconst length = (input as string).length
Angle-bracket syntaxรูปแบบเก่า (ไม่แนะนำใน TSX)const length = (<string>input).length
const assertionระบุว่าเป็นค่าคงที่let colors = ['red', 'green'] as const
Non-null assertionยืนยันว่าไม่ใช่ null/undefineddocument.getElementById('root')!

ข้อควรระวัง

ควรใช้ Type Assertion เท่าที่จำเป็น เพราะอาจทำให้การตรวจสอบ type ไม่ทำงานตามที่คาดหวัง

ts
// ตัวอย่าง as syntax
const 
input
: unknown = "hello";
const
length
= (
input
as string).
length
;
// ตัวอย่าง const assertion const
colors
= ["red", "green"] as
const
;
// colors.push("blue"); // Error: Property 'push' does not exist // ตัวอย่าง non-null assertion function
getElement
(
id
: string) {
return
document
.
getElementById
(
id
)!; // ยืนยันว่าจะไม่เป็น null
}

เมื่อไหร่ควรใช้ Type Assertion

  1. เมื่อทำงานกับ DOM และรู้แน่ชัดว่า element มีอยู่
  2. เมื่อรับค่าจาก external source (เช่น API) และรู้ structure ชัดเจน
  3. เมื่อต้องการเปลี่ยน type ชั่วคราวสำหรับการทำงานบางอย่าง

Type Guard (การตรวจสอบ type ขณะ runtime)

เทคนิคตรวจสอบ type ขณะ runtime เพื่อให้ TypeScript รู้ type ที่แท้จริง

Type Guardวิธีใช้ตัวอย่างการใช้ใช้กับ
typeofตรวจสอบ type พื้นฐานif (typeof x === "string")string, number, boolean, symbol, etc.
instanceofตรวจสอบ instance ของ classif (error instanceof Error)Class
inตรวจสอบว่ามี property ใน object หรือไม่if ("id" in user)Object types
Custom Type Guardสร้างฟังก์ชันตรวจสอบ type เองfunction isFish(pet: Fish | Bird): pet is Fishทุก type
Equality Narrowingใช้การเปรียบเทียบค่าif (x === null)ทุก type
Discriminated Unionใช้ property ร่วมเพื่อแยก typeif (shape.kind === "circle")Union types

Custom Type Guard

การสร้างฟังก์ชันตรวจสอบ type ด้วยตัวเอง โดยใช้ "type predicate" (คืนค่าเป็น parameterName is Type)

ts
interface Fish {
  swim(): void;
}
interface Bird {
  fly(): void;
}

// Custom Type Guard
function isFish(pet: Fish | Bird): pet is Fish {
  return (pet as Fish).swim !== undefined;
}

// ตัวอย่างการใช้งาน
function move(pet: Fish | Bird) {
  if (isFish(pet)) {
    pet.swim(); // TypeScript รู้ว่า pet เป็น Fish
  } else {
    pet.fly(); // TypeScript รู้ว่า pet เป็น Bird
  }
}

Equality Narrowing

ใช้การเปรียบเทียบค่า (===, !==, ==, !=) เพื่อตรวจสอบ type

ts
function printAll(strs: string | string[] | null) {
  if (strs !== null) {
    if (typeof strs === "object") {
      for (const s of strs) { // strs เป็น string[]
        console.log(s);
      }
    } else if (typeof strs === "string") {
      console.log(strs); // strs เป็น string
    }
  }
}

เมื่อไหร่ควรใช้ Type Guard

  1. เมื่อต้องการตรวจสอบ type ขณะ runtime
  2. เมื่อทำงานกับ union types
  3. เมื่อต้องการให้ TypeScript รู้ type ที่แท้จริงใน scope นั้นๆ

ตัวอย่างการใช้งานจริง (Modern Examples)

1. Type Inference กับ React Hooks (ใช้งานบ่อย)

ts
// useState จะอนุมาน type อัตโนมัติจากค่าเริ่มต้น
const [count, setCount] = useState(0); // number
const [user, setUser] = useState(null); // User | null

// ระบุ type ชัดเจนเมื่อค่าเริ่มต้นเป็น null
const [data, setData] = useState<ApiResponse | null>(null);

2. Type Guards กับการตรวจสอบ API Response

ts
// ตรวจสอบโครงสร้างข้อมูลจาก API
function isApiSuccess(response: unknown): response is { data: any } {
  return !!response && typeof response === "object" && "data" in response;
}

// ใช้งาน
const response = await fetchAPI();
if (isApiSuccess(response)) {
  console.log(response.data); // ปลอดภัย
}

3. Discriminated Union กับ Redux Actions

ts
type Action =
  | { type: "ADD_TODO"; payload: string }
  | { type: "TOGGLE_TODO"; id: number }
  | { type: "DELETE_TODO"; id: number };

function reducer(state: State, action: Action) {
  switch (action.type) {
    case "ADD_TODO":
      return [...state, { text: action.payload }];
    case "TOGGLE_TODO":
      // action.id เข้าถึงได้เฉพาะ case นี้
      return state.map(todo =>
        todo.id === action.id ? { ...todo, done: !todo.done } : todo
      );
      // ...
  }
}

4. Type Assertion กับ DOM Elements (ใช้เมื่อมั่นใจ)

ts
// ใน React/Next.js
const videoRef = useRef<HTMLVideoElement>(null);

// ใช้งาน
videoRef.current!.play(); // ! สำหรับ non-null assertion