0Pricing
TypeScript Academy · บทเรียน

ลายเซ็นดัชนีเทียบกับ Record

เลือกใช้ระหว่างลายเซ็นดัชนีกับชนิดยูทิลิตี Record

ลายเซ็นดัชนีเทียบกับ Record เป็นบทเรียน TypeScript Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน TypeScript Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส TypeScript Academy มีบทเรียนทั้งหมด 4 บทเรียน

สองวิธีในการกำหนดชนิดให้แผนที่

TypeScript มีสองวิธีที่ใช้กันทั่วไปในการอธิบายพจนานุกรม ได้แก่ ลายเซ็นดัชนี เช่น { [k: string]: V } และชนิดยูทิลิตีในตัวอย่าง Record<K, V> ทั้งสองแบบมีความสามารถทับซ้อนกันมาก แต่มีรูปแบบการอ่านต่างกัน

ชนิดยูทิลิตี Record

Record<K, V> สร้างชนิดออบเจ็กต์ที่มีคีย์เป็น K และค่าทั้งหมดเป็น V เมื่อใช้ string เป็นคีย์ จะเทียบเท่ากับลายเซ็นดัชนีสตริง

type Scores = Record<string, number>
const game: Scores = { alice: 10, bob: 7 }
console.log(game.alice)

เทียบเท่ากับลายเซ็นดัชนี

ชนิดทั้งสองแบบนี้อธิบายโครงสร้างเดียวกัน Record<string, number> และ { [key: string]: number } ใช้แทนกันได้สำหรับคีย์สตริงใด ๆ

type A = Record<string, number>
type B = { [key: string]: number }
const a: A = { x: 1 }
const b: B = a // assignable both ways
console.log(b.x)

Record กับยูเนียนของคีย์ลิเทอรัล

ความสามารถที่แท้จริงของ Record ปรากฏเมื่อใช้กับยูเนียนแบบจำกัดของคีย์ลิเทอรัล ผลลัพธ์คือออบเจ็กต์ที่มีคีย์ทุกรายการที่ระบุไว้เป็น สิ่งจำเป็น ซึ่งเป็นสิ่งที่ลายเซ็นดัชนีไม่สามารถแสดงได้

type Role = "admin" | "editor" | "viewer"
type Perms = Record<Role, boolean>
const p: Perms = { admin: true, editor: true, viewer: false }
console.log(p.admin)

ตรวจพบคีย์ที่หายไป

เนื่องจากคีย์ลิเทอรัลแต่ละคีย์เป็นสิ่งจำเป็น การลืมคีย์ใดคีย์หนึ่งจะทำให้เกิดข้อผิดพลาดขณะคอมไพล์ นี่เป็นการรับประกันที่รัดกุมซึ่งลายเซ็นดัชนีไม่สามารถให้ได้

type Role = "admin" | "editor" | "viewer"
// const bad: Record<Role, boolean> = { admin: true, editor: true }
// Error: property viewer is missing

ลายเซ็นดัชนีอนุญาตให้ใช้คีย์ใดก็ได้

ในทางตรงกันข้าม ลายเซ็นดัชนีเปิดกว้าง คุณสามารถเพิ่มคีย์ที่ไม่เคยกล่าวถึงที่ใดได้ และไม่จำเป็นต้องมีคีย์ใดอยู่เลย

type Open = { [key: string]: number }
const o: Open = {}      // no keys required
o.anything = 1          // any key allowed
console.log(o.anything)

ชุดคีย์จำกัด: ควรใช้ Record

เมื่อคีย์เป็นชุดที่ทราบแน่ชัดและมีจำนวนจำกัด การใช้ Record ร่วมกับยูเนียนลิเทอรัลจะชัดเจนและปลอดภัยกว่า โดยระบุได้ว่ามีคีย์ใดบ้างและบังคับให้มีครบทุกคีย์

type Direction = "north" | "south" | "east" | "west"
type Moves = Record<Direction, number>
const m: Moves = { north: 1, south: 0, east: 2, west: 0 }
console.log(m.east)

ชุดคีย์เปิดกว้าง: ใช้แบบใดก็ได้

เมื่อคีย์มีจำนวนไม่จำกัดและถูกค้นพบขณะทำงาน ทั้ง Record<string, V> และลายเซ็นดัชนีต่างก็ใช้ได้ หลายทีมเลือก Record เพราะกระชับกว่า ส่วนบางทีมเลือกลายเซ็นเพื่อความชัดเจน

type Cache1 = Record<string, string>
type Cache2 = { [url: string]: string }
const c: Cache1 = {}
c["/home"] = "<html>"
console.log(c["/home"])

Record เป็นเพียงชนิดแมป

ภายในแล้ว Record<K, V> ถูกนิยามเป็นชนิดแมปดังนี้ { [P in K]: V } การทราบเรื่องนี้ช่วยอธิบายว่าเหตุใดยูเนียนลิเทอรัลจึงสร้างคีย์ที่จำเป็น ขณะที่ string สร้างลายเซ็นดัชนี

// lib definition (simplified):
// type Record<K extends string | number | symbol, V> = { [P in K]: V }
type Flags = Record<"a" | "b", boolean>
const f: Flags = { a: true, b: false }
console.log(f.a)

คีย์ที่มีชื่อร่วมกับการรองรับคีย์อื่นทั้งหมด

ลายเซ็นดัชนีสามารถรวมการรองรับคีย์อื่นทั้งหมดเข้ากับคีย์ตายตัวในอินเทอร์เฟซเดียว ซึ่งสะดวกเมื่อต้องการทั้งสองอย่าง ส่วน Record เพียงอย่างเดียวไม่สามารถรวมคีย์ที่มีชื่อและจำเป็นเข้ากับการรองรับคีย์อื่นทั้งหมดที่เปิดกว้างได้อย่างเรียบร้อยเท่า

interface Response {
  status: number
  [header: string]: number | string
}
const r: Response = { status: 200, "x-id": "abc" }
console.log(r.status)

การเลือกใช้ในทางปฏิบัติ

หลักง่าย ๆ คือ คีย์มีจำนวนจำกัดและทราบแน่ชัด → ใช้ Record<Union, V> เพื่อตรวจสอบว่ามีครบทุกคีย์ คีย์มีจำนวนไม่จำกัด → ใช้แบบใดก็ได้ ต้องการคีย์ที่มีชื่อร่วมกับการรองรับคีย์อื่นทั้งหมด → ใช้ลายเซ็นดัชนีภายในอินเทอร์เฟซ

type Status = "ok" | "error"
type Messages = Record<Status, string>
const msg: Messages = { ok: "done", error: "failed" }
console.log(msg.ok)

ตรวจสอบความเข้าใจ

ทดสอบความเข้าใจเกี่ยวกับ Record และลายเซ็นดัชนี

สรุปทบทวน

Record<string, V> เท่ากับลายเซ็นดัชนีสตริง แต่ Record ที่ใช้ยูเนียนของคีย์ลิเทอรัลจะทำให้คีย์ที่ระบุไว้ทุกคีย์เป็นสิ่งจำเป็น จึงตรวจพบคีย์ที่ขาดหายขณะคอมไพล์ ใช้ Record<Union, V> สำหรับคีย์ที่มีจำนวนจำกัดและทราบแน่ชัด ใช้แบบใดก็ได้สำหรับคีย์ที่มีจำนวนไม่จำกัด และใช้ลายเซ็นดัชนีเมื่อต้องการคีย์ที่มีชื่อร่วมกับการรองรับคีย์อื่นทั้งหมด ภายในแล้ว Record คือชนิดแมป { [P in K]: V }

คำถามที่พบบ่อย

บทเรียน “ลายเซ็นดัชนีเทียบกับ Record” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “ลายเซ็นดัชนีเทียบกับ Record” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส TypeScript Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส TypeScript Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “ลายเซ็นดัชนีเทียบกับ Record”

เลือกใช้ระหว่างลายเซ็นดัชนีกับชนิดยูทิลิตี Record คุณปฏิบัติ TypeScript Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน TypeScript Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน TypeScript Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “ลายเซ็นดัชนีเทียบกับ Record” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน TypeScript Academy นี้ได้ไหม

ได้ บทเรียน TypeScript Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การกำหนดลายเซ็นดัชนี
  2. ลายเซ็นดัชนีแบบสตริงเทียบกับตัวเลข
  3. การรวมคีย์ที่ทราบกับคีย์แบบไดนามิก
  4. ลายเซ็นดัชนีเทียบกับ Record
← กลับไปที่ TypeScript Academy