ข้ามไปเนื้อหาหลัก

TypeScript Mapped Types — แปลง type ทุก key พร้อมกัน

Mapped Type สร้าง type ใหม่โดยวนซ้ำ key ของ type เดิมแล้วแปลงแต่ละตัว เป็น base ของ utility types อย่าง Partial, Readonly, Record

// สร้าง Partial เอง — ทำให้ทุก property optional
type MyPartial<T> = {
  [K in keyof T]?: T[K];
};

// Readonly — ทำให้ทุก property อ่านได้อย่างเดียว
type MyReadonly<T> = {
  readonly [K in keyof T]: T[K];
};

// Nullable — ทำให้รับ null ได้ทุก property
type Nullable<T> = {
  [K in keyof T]: T[K] | null;
};

Key remapping ด้วย as:

// เพิ่ม prefix ทุก key
type Prefixed<T, P extends string> = {
  [K in keyof T as `${P}${Capitalize<string & K>}`]: T[K];
};

type User = { name: string; age: number };
type PrefixedUser = Prefixed<User, 'user'>;
// = { userName: string; userAge: number }

Filter key ด้วย never:

// เอาเฉพาะ key ที่ value เป็น string
type StringValues<T> = {
  [K in keyof T as T[K] extends string ? K : never]: T[K];
};

type Config = { host: string; port: number; debug: boolean; name: string };
type StringConfig = StringValues<Config>;
// = { host: string; name: string }

Mapped Types + Template Literal Types + Conditional Types = Utility types ที่ซับซ้อนมาก แต่เข้าใจแต่ละชิ้นก่อน แล้วค่อยประกอบ