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

reflect-metadata และชนิดข้อมูลการออกแบบ

จับชนิดข้อมูลของพารามิเตอร์และคุณสมบัติขณะทำงาน

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

เมทาดาทาแบบสะท้อนกลับและชนิดขณะออกแบบ

ก่อนจะมีเมทาดาทาที่เป็นมาตรฐาน TypeScript สามารถส่งออกข้อมูลชนิดขณะออกแบบไปยังรันไทม์ผ่านไลบรารี reflect-metadata พร้อมกับแฟล็กคอมไพเลอร์ emitDecoratorMetadata บทเรียนนี้ครอบคลุมกลไกรุ่นเก่านี้ ซึ่งยังมีการใช้งานอย่างแพร่หลาย

การเปิดใช้ความสามารถนี้

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

// tsconfig.json
// {
//   "compilerOptions": {
//     "experimentalDecorators": true,
//     "emitDecoratorMetadata": true
//   }
// }

import "reflect-metadata";

สิ่งที่ถูกส่งออก

เมื่อใช้ emitDecoratorMetadata คอมไพเลอร์จะส่งออกคีย์สามรายการสำหรับสมาชิกที่มีเดคอเรเตอร์ ได้แก่ design:type, design:paramtypes และ design:returntype ค่าเหล่านี้คือฟังก์ชันตัวสร้าง เช่น String และ Number

การอ่านชนิดขณะออกแบบ

สำหรับพร็อพเพอร์ตีที่มีเดคอเรเตอร์ Reflect.getMetadata("design:type", target, key) จะส่งคืนตัวสร้างชนิดของพร็อพเพอร์ตี

import "reflect-metadata";

function track(target: any, key: string) {
  const t = Reflect.getMetadata("design:type", target, key);
  console.log(key, "->", t.name); // e.g. "name -> String"
}

class Person {
  @track name!: string;
  @track age!: number;
}

การอ่านชนิดพารามิเตอร์ขณะออกแบบ

ในตัวสร้างหรือเมธอด design:paramtypes คืออาร์เรย์ของตัวสร้างชนิดพารามิเตอร์ ซึ่งเป็นรากฐานของ DI

function injectable(target: any) {
  const params = Reflect.getMetadata("design:paramtypes", target);
  console.log(params.map((p: any) => p.name)); // ["Database", "Logger"]
}

@injectable
class Service {
  constructor(private db: Database, private log: Logger) {}
}

ข้อจำกัดของชนิดที่ส่งออก

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

เมทาดาทาแบบกำหนดเองด้วยการสะท้อน

คุณยังสามารถกำหนดคีย์เมทาดาทาของคุณเองด้วย Reflect.defineMetadata โดยไม่ขึ้นกับชนิดขณะออกแบบ

import "reflect-metadata";

function required(target: any, key: string) {
  Reflect.defineMetadata("required", true, target, key);
}

function isRequired(target: any, key: string) {
  return Reflect.getMetadata("required", target, key) === true;
}

การใช้งาน

กลไกนี้อยู่เบื้องหลังเฟรมเวิร์กที่ใช้งานมายาวนานหลายตัว เช่น NestJS, TypeORM และตัวตรวจสอบคลาส เฟรมเวิร์กเหล่านี้อ่าน design:type และ design:paramtypes เพื่อเชื่อมโยงการพึ่งพาและตรวจสอบค่า โดยไม่ต้องให้คุณระบุชนิดซ้ำ

เมทาดาทาแบบสะท้อนกลับเทียบกับเมทาดาทามาตรฐาน

API Symbol.metadata ใหม่เป็นส่วนหนึ่งของภาษา และไม่ได้ส่งออกชนิดขณะออกแบบ ส่วน reflect-metadata ให้ข้อมูลชนิดโดยเฉพาะ แต่ผูกอยู่กับโหมดเดคอเรเตอร์แบบทดลอง ควรเลือกใช้รูปแบบใดรูปแบบหนึ่งต่อหนึ่งโครงการ

ลำดับการนำเข้ามีความสำคัญ

import "reflect-metadata" ต้องทำงานครั้งเดียว ก่อนที่จะประเมินคลาสที่มีเดคอเรเตอร์ใด ๆ เนื่องจากคำสั่งนี้ปรับแก้วัตถุ Reflect ทั่วโลกด้วยฟังก์ชันเมทาดาทา ให้นำเข้าไว้บนสุดของไฟล์ทางเข้าโปรแกรม

เหตุใดจึงสำคัญ

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

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

ทดสอบความเข้าใจเกี่ยวกับเมทาดาทาแบบสะท้อนกลับของคุณ

สรุปทบทวน

เมื่อใช้ experimentalDecorators ร่วมกับ emitDecoratorMetadata และมี import "reflect-metadata" ตั้งแต่ต้น คอมไพเลอร์จะส่งออก design:type และ design:paramtypes เป็นตัวสร้างที่ใช้ขณะรันไทม์ เฟรมเวิร์กจะอ่านข้อมูลเหล่านี้เพื่อทำ DI และการตรวจสอบ แม้ว่าอินเทอร์เฟซ ยูเนียน และเจเนอริกจะลดรูปเป็น Object ก็ตาม

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

บทเรียน “reflect-metadata และชนิดข้อมูลการออกแบบ” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “reflect-metadata และชนิดข้อมูลการออกแบบ”

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

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

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

บทเรียน “reflect-metadata และชนิดข้อมูลการออกแบบ” ใช้เวลานานแค่ไหน

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

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

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

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

  1. อธิบายเดคอเรเตอร์ระยะที่ 3
  2. ข้อมูลเมทาดาทาของเดคอเรเตอร์
  3. reflect-metadata และชนิดข้อมูลการออกแบบ
  4. การสร้างเฟรมเวิร์กเดคอเรเตอร์
← กลับไปที่ TypeScript Academy