TypeScript 데코레이터

여러분, 안녕하세요! 오늘은 TypeScript 데코레이터에 대해 이야기하겠습니다. 그들은 솔직히 놀랍고 다양한 라이브러리와 응용 프로그램에서 사용됩니다.

그래서 우선 그들은 무엇을 하는가?

"데코레이터는 클래스, 메소드, 접근자, 속성 또는 매개변수의 맨 위에 첨부할 수 있는 특수 선언입니다. 데코레이터는 @Decorator 형식을 사용합니다. 여기서 표현식은 런타임에 호출될 함수로 평가되어야 합니다. 장식 선언."TypeScript 문서 자체를 말합니다. 기사 마지막에 링크를 걸어 놓겠습니다. 데코레이터에 대한 자세한 정보를 보려면 반드시 읽어야 합니다!

더 이상 할 필요 없이 예제를 보고 수행하는 작업을 이해해 보겠습니다.

function Configurable(value: boolean) {
  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    descriptor.configurable = value;
  };
}

function Logger(target: any, propertyKey: string) {
  console.log(`Target is: ${target}`);
  console.log(`Property Key is: ${propertyKey}`);
}

class ExampleClass {
  @Logger
  private _x: number;

  constructor(x: number) {
    this._x = x;
  }

  @Configurable(false)
  get x() {
    return this._x;
  }
}


위의 코드는 기본적으로 접근자 기능을 구성할 수 없게 만들고 액세스하는 속성만 기록합니다.

그러나 설명서와 이 예제의 모든 복잡한 내용은 무엇을 의미합니까? 사실 매우 간단합니다. 데코레이터는 장식하기 위해 넣은 속성에 대한 정보가 있는 함수일 뿐이며 런타임에 호출됩니다!

더 잘 이해하기 위해 실제 데코레이터 사용의 다른 예를 살펴보겠습니다.

function Sealed(constructor:Function) {
  Object.seal(constructor);
  Object.seal(constructor.prototype);
}

@Sealed
class ExampleClass {
  // methods
}


위의 스니펫에서 Sealed 데코레이터는 클래스가 새로운 기능을 추가하거나 제거하지 못하도록 봉인합니다.

아래 예제에서는 함수에 매개변수를 장식하는 데 사용할 수 있는 데코레이터 유형을 보여줍니다. 이 경우 매개 변수를 가져오고 이를 사용하여 항목을 정의하려면 "reflect-metadata"패키지가 필요합니다.

import "reflect-metadata";
const requiredMetadataKey = Symbol("Required");

function Required(target: Object, propertyKey: string | symbol, parameterIndex: number {
  let existingRequiredParameters: number[] = Reflect.getOwnMetadata(requiredMetadataKey, target, propertyKey) || [];
  existingRequiredParameters.push(parameterIndex);
  Reflect.defineMetadata( requiredMetadataKey, existingRequiredParameters, target, propertyKey);
}

class ExampleClass {
  sayName(@Required name: string) {
    console.log(`Your name is: ${name}`);
  }
}


위의 예에서 우리는 항목을 추가하기 위해 메타데이터를 사용하여 데코레이션하는 매개변수를 필수로 만드는 데코레이터를 작성했습니다.

첫 번째 예에서와 같이 메서드를 꾸밀 수 있고 데코레이터 함수에 변수를 전달할 수도 있으므로 이를 수행하는 데코레이터 팩토리를 만들 수 있습니다. 기본적으로 래퍼 함수를 ​​만들고 거기에서 변수를 가져온 다음 래퍼 함수에서 가져온 인수와 함께 데코레이터를 사용합니다. 예는 다음과 같습니다.

function Readonly(value: boolean) {
  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    descriptor.writable = value;
  };
}

class Test {
  @Readonly(true)
  sayHello() {
    console.log("Hello there!");
  }
}


위의 예에서 우리는 속성 설명자를 사용하여 데코레이터에 지정된 매개 변수로 쓰기 가능한 값을 수정했습니다. 읽기 전용이 됩니다.

생각해보면 반환된 함수가 취하는 매개변수는 무엇입니까? 간단히 말해서 target은 데코레이터에 넣은 값입니다. 속성 키는 해당 대상에 부여한 변수 이름입니다. 그리고 설명자(때로는 특정 값에 존재하지 않음)는 우리가 구성할 수 있는 값에 대한 설명입니다. 설명자가 존재하지 않는 이유는 특정 데코레이터가 다른 데코레이터와 다르기 때문입니다. 예를 들어 클래스 데코레이터는 생성자라는 하나의 인수만 사용합니다. 메서드 데코레이터는 3개를 모두 사용하는 반면 접근자 데코레이터는 3개의 인수도 사용하지만 스크립트 대상이 ES5 미만인 경우 세 번째 인수를 사용하지 않습니다. 속성 데코레이터는 처음 두 개만 인수로 사용합니다. 매개변수 데코레이터는 세 개의 인수를 사용하지만 마지막 인수는 설명자가 아닌 매개변수 인덱스입니다. 예를 들어 클래스 데코레이터에 대한 세 가지 인수를 모두 제공하면 확실히 오류가 발생하므로 이를 염두에 두십시오.

데코레이터는 많은 것들에 사용될 수 있습니다. 그리고 class-validator와 같은 많은 중요한 라이브러리와 NestJS와 같은 프레임워크에서 이를 사용합니다.

이 기사는 데코레이터 주제에 쉽게 접근할 수 있도록 TypeScript 문서에서 많은 영감을 받았습니다.

이제 이 기사를 읽고 데코레이터가 무엇을 하는지 이해했으므로 공식 문서를 읽는 것이 좋습니다! 여기에 대한 링크가 있습니다: TypeScript Decorator Documentation

항상 그렇듯이 기사에 대한 귀하의 의견을 듣고 싶습니다. 의견에 나와 이야기하십시오!

좋은 하루 되세요!

좋은 웹페이지 즐겨찾기