[NestJS] Decorator 동작 원리

## nestjs보다가 "@". 궁금한 건 못참지.
- Nestjs에 있는 @데코레이터
- 관련 자료를 찾아보니
	-  https://mirone.me/a-complete-guide-to-typescript-decorator/
	-  https://devblogs.microsoft.com/typescript/announcing-typescript-5-0/#decorators
	- https://www.typescriptlang.org/docs/handbook/decorators.html
- 흠.... 뭔말인지 잘 모르겠음. 
## 우선은 삽질. 타입스크립트 프로젝트 세팅
- package.json

```sh
{
  "name": "typescript-exercise",
  "version": "1.0.0",
  "description": "",
  "type": "module",
  "scripts": {
    "start": "node ./build/main.js"
  },
  "author": "",
  "license": "ISC"
  
}
```

- tsconfig.json

```json
{
  "compilerOptions": {
    "module": "ESNext",  
    "outDir": "./build",  
    "esModuleInterop": true,  
    "forceConsistentCasingInFileNames": true, 
    "strict": true,                                     
    "skipLibCheck": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
  }
}
```

## 자꾸 빨간줄...nestjs 소스 까보기
- tsconfig 에 옵션켜주어야함.
```json
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
```
- 항상 그렇지만 문제가 해결되고 나면 이런 내용이 인터넷에 있는 것을 발견함. 
	- https://wikidocs.net/book/7059
## 이제 설명할 수 있을 거 같아요
- 현재 Decorator에 대한 표준화가 진행중이다. 
- 타입스크립트에서는 5.0부터 데코레이터 기능을 제공한다. 
- Nestjs 가 과감히 Decorator를 도입했다. (잘했다)

## 본격적인 Decorator 실험
```ts
// main.ts
import { Person } from './Person.js'

const matthew = new Person ("matthew", 4)
console.log(matthew.getNickname())
console.log(matthew.getName())
```

```ts
// person.ts
@Controller()
export class Person {
    [x: string]: any;
    constructor(private name: string, private age: number) { }

    @Logger()
    getName() {
        return this.name
    }
}

function Controller(): ClassDecorator {
    return (target: any) => {
        target.prototype.getNickname = function () {
            return this.name + " is my nickname";
        }
        return target;
    }
}

function Logger(): MethodDecorator {
    return (target, propertyKey, descriptor: TypedPropertyDescriptor): void => {
        console.log("=====================================")
        console.log(target, " =========== ", propertyKey, " =========== ", descriptor);
        descriptor.value = function () {
            console.log("function 변경")
        }
        console.log("=====================================")

    }
}
```
## 마무리
- `"reflect-metadata": "0.1.14"`
- 결과는 스프링부트와 마찬가지로 refection을 사용. 
- dependency inversion은 reflection이 답인가..
- nestjs 안 할 이유가 없네요.

댓글

이 블로그의 인기 게시물

Session 대신 JWT를 사용하는 이유

VSCode에서의 VIM 단축키와 키보드 구매 가이드

우분투에서 테스트링크(testlink)와 맨티스(mantis)로 테스팅 서버 구성하기