Frontend Academy · บทเรียน

เดคอเรเตอร์และข้อมูลเมตา

เปิดใช้เดคอเรเตอร์ทดลอง เขียนเดคอเรเตอร์สำหรับคลาส เมธอด และคุณสมบัติ และใช้ reflect-metadata กับรูปแบบการฉีดการพึ่งพา

บทเรียน 2 จาก 414 ขั้นตอน

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

เดคอเรเตอร์คืออะไร

เดคอเรเตอร์คือฟังก์ชันที่แก้ไขคลาส เมธอด พร็อพเพอร์ตี หรือพารามิเตอร์ในเวลาที่มีการประกาศใช้งาน เดคอเรเตอร์ถูกใช้มากใน Angular, NestJS, TypeORM และ MobX แบบใช้คลาส

ไวยากรณ์ของเดคอเรเตอร์

ใส่ @DecoratorName ไว้หน้าคลาส เมธอด พร็อพเพอร์ตี หรือพารามิเตอร์ ฟังก์ชันเดคอเรเตอร์จะทำงานเมื่อมีการประกาศคลาส

@Component({ selector: 'app-root' })
export class AppComponent {
  @Input() title: string;

  @HostListener('click')
  onClick() {
    console.log('clicked');
  }
}

การเปิดใช้งานเดคอเรเตอร์

เปิดใช้แฟล็กเชิงทดลองใน tsconfig.json ส่วนเดคอเรเตอร์มาตรฐาน ECMAScript ระยะที่ 3 (TypeScript 5.0 ขึ้นไป) ไม่ต้องใช้แฟล็กนี้ แต่มีความหมายในการทำงานแตกต่างกัน

{
  "compilerOptions": {
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }
}

เดคอเรเตอร์คลาส

ได้รับคอนสตรักเตอร์เป็นอาร์กิวเมนต์ สามารถแทนที่ ห่อหุ้ม หรือเพิ่มความสามารถให้คลาสได้

function Singleton<T extends { new (...a: any[]): {} }>(target: T) {
  let instance: T;
  return class extends target {
    constructor(...args: any[]) {
      if (!instance) instance = new target(...args) as T;
      return instance;
    }
  };
}

@Singleton
class Logger { /* ... */ }

เดคอเรเตอร์เมธอด

ได้รับ (เป้าหมาย, คีย์, ตัวบอกลักษณะ) และสามารถห่อหุ้มเมธอดได้ เช่น เพื่อบันทึกการเรียกใช้

function Log(target: any, key: string, descriptor: PropertyDescriptor) {
  const original = descriptor.value;
  descriptor.value = function (...args: any[]) {
    console.log(`[${key}]`, args);
    return original.apply(this, args);
  };
}

class Service {
  @Log
  greet(name: string) { return `Hello ${name}`; }
}

เดคอเรเตอร์พร็อพเพอร์ตี

ได้รับ (เป้าหมาย, คีย์) และมักใช้ร่วมกับ reflect-metadata เพื่อลงทะเบียนข้อมูลเกี่ยวกับพร็อพเพอร์ตี

function Required(target: any, key: string) {
  const existing = Reflect.getMetadata('required', target) || [];
  Reflect.defineMetadata('required', [...existing, key], target);
}

class User {
  @Required name: string;
  @Required email: string;
}

เดคอเรเตอร์พารามิเตอร์

ได้รับ (เป้าหมาย, คีย์, parameterIndex) และใช้สำหรับการฉีดการพึ่งพา โดยบันทึกว่าพารามิเตอร์ใดต้องใช้บริการใด

function Inject(token: string) {
  return function (target: any, key: string, index: number) {
    const existing = Reflect.getMetadata('inject', target, key) || {};
    existing[index] = token;
    Reflect.defineMetadata('inject', existing, target, key);
  };
}

class UserService {
  constructor(@Inject('Database') db: Database) {}
}

reflect-metadata

reflect-metadata คือโพลีฟิลล์ที่ช่วยให้เดคอเรเตอร์อ่านและเขียนเมทาดาทาบนคลาสได้ จำเป็นสำหรับ Angular DI และ ORM หลายรูปแบบ

npm install reflect-metadata

// main.ts (entry point):
import 'reflect-metadata';

import { Reflect } from 'reflect-metadata';
Reflect.defineMetadata('key', 'value', target);
Reflect.getMetadata('key', target); // 'value'

โรงงานเดคอเรเตอร์

โรงงานจะส่งคืนเดคอเรเตอร์ และใช้สำหรับส่งอาร์กิวเมนต์

function Component(config: { selector: string }) {
  return function (target: any) {
    target.selector = config.selector;
  };
}

@Component({ selector: 'app-root' })
class AppComponent {}

กรณีใช้งานด้านการตรวจสอบความถูกต้อง

รวมเดคอเรเตอร์พร็อพเพอร์ตีเข้ากับฟังก์ชันตรวจสอบความถูกต้อง เพื่อสร้างไลบรารีตรวจสอบความถูกต้องขนาดเล็ก

// Decorator records that a field is required:
function Required(target: any, key: string) {
  const fields = Reflect.getMetadata('required', target) || [];
  Reflect.defineMetadata('required', [...fields, key], target);
}

class User {
  @Required name!: string;
  @Required email!: string;
}

function validate(obj: any): string[] {
  const required: string[] = Reflect.getMetadata('required', obj) || [];
  return required.filter(k => obj[k] == null);
}

เดคอเรเตอร์ระยะที่ 3 (TC39)

เดคอเรเตอร์มาตรฐาน (TS 5.0 ขึ้นไป รองรับใน Node 22 ขึ้นไปเมื่อเปิดใช้แฟล็ก) มีลายเซ็นแตกต่างออกไป ไม่ต้องใช้แฟล็กเชิงทดลองและไม่ต้องใช้ reflect-metadata

ควรใช้เดคอเรเตอร์เมื่อใด

ใช้เดคอเรเตอร์เมื่อเฟรมเวิร์กมีเดคอเรเตอร์ให้ใช้ (Angular, NestJS, TypeORM) อย่าสร้างเดคอเรเตอร์เองในโค้ดส่วนหน้าแบบทั่วไป เพราะจะเพิ่มความซับซ้อนและผูกโค้ดไว้กับพฤติกรรมเฉพาะของรันไทม์

ตรวจสอบความเข้าใจอย่างรวดเร็ว

ต้องเปิดใช้แฟล็กใดใน tsconfig.json เพื่อใช้เดคอเรเตอร์แบบเก่า (เชิงทดลอง) ร่วมกับการสะท้อนเมทาดาทา

สรุป: เดคอเรเตอร์

เดคอเรเตอร์แก้ไขคลาส เมธอด พร็อพเพอร์ตี และพารามิเตอร์ในเวลาที่มีการประกาศใช้งาน เปิดใช้ experimentalDecorators + emitDecoratorMetadata ลายเซ็นของเดคอเรเตอร์คลาส เมธอด พร็อพเพอร์ตี และพารามิเตอร์แตกต่างกัน reflect-metadata ใช้จัดเก็บเมทาดาทา ส่วนโรงงานใช้ส่งอาร์กิวเมนต์ เดคอเรเตอร์ถูกใช้อย่างมากใน Angular, NestJS และ TypeORM เดคอเรเตอร์ระยะที่ 3 (TS 5 ขึ้นไป) คือแนวทางในอนาคตและไม่ต้องใช้แฟล็ก

เริ่มต้นได้ฟรี

เรียนรู้ HTML ด้วย AI tutor — ฟรี

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

คอร์ส
41
บทเรียน
163

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

บทเรียน “เดคอเรเตอร์และข้อมูลเมตา” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “เดคอเรเตอร์และข้อมูลเมตา”

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

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

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

บทเรียน “เดคอเรเตอร์และข้อมูลเมตา” ใช้เวลานานแค่ไหน

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

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

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

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

  1. ชนิด Template Literal
  2. เดคอเรเตอร์และข้อมูลเมตา
  3. TypeScript กับ React: เจเนริกของ FC และฮุก
  4. โหมดเข้มงวดและการกำจัด any
← กลับไปที่ Frontend Academy