일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 트랜잭션 격리
- Spock Stub
- Spock Mock
- enum
- Vue+Typescript
- Javascript
- 공짜로 Docker Desktop같은거 쓰기
- vue store
- mock stub spy
- @Transaction isolation
- mock stub
- nuxtjs/composition-api buildModules
- Rancher Desktop설치
- TypeScript
- 타입스크립트
- Docker Desktop 쓰고싶다
- 자바스크립트
- Mock vs Stub
- DI
- 의존성주입
- docker desktop 유료화 정책
- docker desktop 대체
- frontend
- ECMAScript
- webpack
- TCP/IP
- Spock Spy
- @Transaction propagation
- Spock Mock Stub Spy
- HTTP란
- Today
- Total
끄적끄적
[타입스크립트] 데코레이터(Decorator) 본문
타입스크립트의 데코레이터에 대해서 알아보고 정리해 보고자 합니다.
타입스크립트로 개발을 진행하다보면 필연적으로 데코레이터란 것을 접하게 됩니다. 자바를 경험한 사람이라면 어노테이션과 굉장히 흡사하다고 생각이 들 정도로 비슷하게 보이더라구요 (제가...그렇습니다.) 데코레이터는 함수 라고 할 수 있습니다. 데코레이터는 말 그대로 코드 조각을 장식해주는 역할을 하며 타입스크립트에서는 그 기능을 함수로 구현할 수 있습니다.
데코레이터(decorator)
- 데코레이터는 클래스 선언, 메서드, 접근자, 프로퍼티 또는 매개 변수에 첨부할 수 있는 특수한 종류의 선언입니다.
- 데코레이터 함수에는 target(현재타겟), key(속성이름), descriptor(설명)가 전달됩니다.
- 메소드나 클래스 인스턴스가 만들어지는 런타임에 실행됩니다. 즉, 매번 실행되지 않습니다.
- 메서드, 접근자 또는 프로퍼티 데코레이터가 다음에 오는 매개 변수 데코레이터는 각 인스턴스 멤버에 적용됩니다.
- 메서드, 접근자 또는 프로퍼티 데코레이터가 다음에 오는 매개 변수 데코레이터는 각 정적 멤버에 적용됩니다.
- 매개 변수 데코레이터는 생성자에 적용됩니다.
- 클래스 데코레이터는 클래스에 적용됩니다.
Setup
$ npm install babel-core babel-plugin-transform-decorators-legacy --save-dev
/* .babelrc */
{
//...
"plugins": ["transform-decorators-legacy"]
}
tsconfig에 아래의 코드를 변경해 줍니다.
tsc --target ES5 --experimentalDecorators
/* tsconfig.json */
{
"compilerOptions": {
"target": "ES5",
"experimentalDecorators": true
}
}
Class Decorator
클래스 데코레이터는 클래스 선언 직전에 선언됩니다. 클래스 데코레이터는 클래스 생성자에 적용되며 클래스 정의를 관찰, 수정 또는 교체하는 데 사용할 수 있습니다.
function classDecorator<T extends {new(...args:any[]):{}}>(constructor:T) {
return class extends constructor {
hello = "test2";
}
}
@classDecorator
class Example {
test:string;
constructor(m: string) {
this.hello = m;
}
}
Method decorator
메서드 데코레이터는 메서드 선언 직전에 선언됩니다. 메서드 관찰, 수정 또는 대체하는 데 사용할 수 있습니다.
function readOnly() {
return function (target, propertyKey: string, descriptor: PropertyDescriptor) {
descriptor.writable = false;
return descriptor;
}
}
class Example {
@readOnly
test(): string {
return 'test';
}
}
Accessor Decorators
접근자 데코레이터는 접근자 선언 바로 전에 선언됩니다. 접근자 데코레이터는 접근자의 프로퍼티 설명자에 적용되며 접근자의 정의를 관찰, 수정 또는 교체하는 데 사용할 수 있습니다.
function configurable(value: boolean) {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
descriptor.configurable = value;
};
}
class Point {
private _x: number;
private _y: number;
constructor(x: number, y: number) {
this._x = x;
this._y = y;
}
@configurable(false)
get x() { return this._x; }
@configurable(false)
get y() { return this._y; }
}
Property Decorators
프로퍼티 데코레이터는 프로퍼티 선언 바로 전에 선언됩니다. 프로퍼티 데코레이터는 선언 파일이나 다른 주변 컨텍스트에서 사용할 수 없습니다.
import "reflect-metadata";
const formatMetadataKey = Symbol("format");
function format(formatString: string) {
return Reflect.metadata(formatMetadataKey, formatString);
}
function getFormat(target: any, propertyKey: string) {
return Reflect.getMetadata(formatMetadataKey, target, propertyKey);
}
class Example {
@format("test, %s")
text: string;
constructor(message: string) {
this.text = message;
}
test() {
let formatString = getFormat(this, "test");
return formatString.replace("%s", this.text);
}
}
Parameter Decorators
매개변수 데코레이터는 매개 변수 선언 직전에 선언됩니다. 매개변수 데코레이터는 클래스 생성자 또는 메서드 선언의 함수에 적용됩니다. 매개변수 데코레이터는 선언 파일, 오버로드 또는 다른 주변 컨텍스트에서 사용할 수 없습니다.
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 Example {
test(@required text: string) {
return text;
}
}
여러형태의 데코레이터를 만들어 프로젝트에서 쓰게 된다면 조금 더 코드에 대한 퀄리티와 관심사에 대해서 데코레이터로 만들어 둔어 라이브러리 형태로 만들어 둔다면 꽤나 편하게 개발 할 수 있을 것 같다는 생각이 듭니다.
아래의 링크를 통해 조금 더 많은 정보를 얻을 수 있습니다.
참고
'Front-end > Typescript' 카테고리의 다른 글
[타입스크립트] Enum 클래스로 사용해보기 (0) | 2021.11.18 |
---|---|
타입스크립트 프로젝트 만들기 - 패키지 구성 알아보기 (0) | 2019.05.31 |
타입스크립트 프로젝트 만들기 - 타입정의 (0) | 2019.05.30 |
타입스크립트 프로젝트 만들기 - 개발환경세팅 (0) | 2019.05.27 |
타입스크립트란? (0) | 2019.05.26 |