Skip to content

Type Safety in TypeScript (ความปลอดภัยของประเภทข้อมูล)

เทคนิคการเขียน TypeScript ให้มีความปลอดภัยทางประเภทข้อมูลสูงสุด ลดข้อผิดพลาดขณะ runtime

1. Strict Mode (โหมดเข้มงวด)

ts
// tsconfig.json
{
  "compilerOptions": {
    "strict": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "strictFunctionTypes": true,
    "strictBindCallApply": true,
    "strictPropertyInitialization": true
  }
}

ประโยชน์:

  • ตรวจสอบ type อย่างเข้มงวดขณะ compile-time
  • ป้องกันการใช้ any โดยไม่จำเป็น
  • บังคับตรวจสอบ null/undefined

2. Type Annotations (การระบุประเภทชัดเจน)

ts
// ระบุ type ชัดเจน
function calculateTotal(price: number, quantity: number): number {
  return price * quantity;
}

// ใช้ type inference เมื่อเหมาะสม
const items = [1, 2, 3]; // TypeScript รู้ว่าเป็น number[]

3. Null Safety (การจัดการ null/undefined)

ts
// ใช้ optional chaining (?.)
const userName = user?.profile?.name ?? "Guest";

// ใช้ null checks
function formatDate(date?: Date) {
  if (!date) return "N/A";
  return date.toISOString();
}

4. Type Guards (การป้องกันประเภท)

ts
// typeof guards
function process(input: string | number) {
  if (typeof input === "string") {
    return input.toUpperCase();
  }
  return input.toFixed(2);
}

// Custom type guards
function isAdmin(user: User): user is Admin {
  return "permissions" in user;
}

5. Immutable Patterns (รูปแบบไม่เปลี่ยนแปลง)

ts
// ใช้ readonly
interface Config {
  readonly apiUrl: string;
  readonly timeout: number;
}

// ใช้ const assertions
const colors = ["red", "green", "blue"] as const;

6. Runtime Validation (การตรวจสอบขณะรัน)

ts
import { z } from "zod";

const UserSchema = z.object({
  id: z.string().uuid(),
  email: z.string().email(),
  age: z.number().min(18),
});

type User = z.infer<typeof UserSchema>;

function createUser(input: unknown): User {
  return UserSchema.parse(input);
}

7. Branded Types (ประเภทเฉพาะ)

ts
type Email = string & { readonly __brand: "Email" };

type Password = string & { readonly __brand: "Password" };

function createEmail(email: string): Email {
  if (!email.includes("@")) throw new Error("Invalid email");
  return email as Email;
}

8. Utility Types (ประเภทอรรถประโยชน์)

ts
// ใช้ Pick, Omit, Partial อย่างเหมาะสม
interface Product {
  id: string;
  name: string;
  price: number;
  description?: string;
}

type ProductPreview = Pick<Product, "id" | "name">;

type ProductUpdate = Partial<Omit<Product, "id">>;

9. Error Handling (การจัดการข้อผิดพลาด)

ts
class ApiError extends Error {
  constructor(
    public readonly code: number,
    message: string,
  ) {
    super(message);
  }
}

function fetchData() {
  try {
    // ...
  } catch (error) {
    if (error instanceof ApiError) {
      // จัดการ error เฉพาะ
    }
    throw error; // ปล่อยผ่าน error ที่ไม่รู้จัก
  }
}

10. Testing Types (การทดสอบประเภท)

ts
// ใช้ @ts-expect-error เพื่อทดสอบ type errors
// @ts-expect-error - ควร error เพราะรับ number เท่านั้น
const invalid: number[] = ["not a number"];

// ใช้ satisfies operator
const config = {
  apiUrl: "https://api.example.com",
  timeout: 5000,
} satisfies AppConfig;