NestJS와 Typescript5의 엇갈린 만남

원래 사람은 잘 안변해·2023년 4월 14일
2

들어가기에 앞서

이 글은 작성 시점인 2023년 4월 15일을 기준으로 작성되었습니다.
시간에 따라 Nest.js와 Typescript Decorator의 구현에 차이가 있을 수 있으니 변경점을 발견하신다면 언제든 댓글 달아주세요!

TL;DR

  1. Typescript 5에 Decorator가 실험적 기능을 벗어나 정식 기능으로 출시되었습니다.
  2. 그런데 들어오면서 기존의 실험 방식과는 완전 다른 형태의 파라미터를 가지게 되었습니다.
  3. 해당 기능을 통해 AOP를 구현하고 있던 Nest.js는 당분간 --experimentalDecorators의 사용을 유지하기로 하였습니다.

본문

2023년 3월 16일. 드디어 Typescript5가 출시되었습니다.

자세한 변경 사항은 링크를 참고해 주세요.

이 중에서도 눈여겨 볼 점이 바로 Decorator가 정식으로 도입되었다는 점인데요, NestJS등 여러 프레임워크와 라이브러리에서 사용하고 있는 기능이니만큼 언젠가는 정식 기능으로 도입될거라고 생각했죠. 그런데....

달라져버린 구현

기존 NestJS는 클래스 / 메소드 / 접근자 / 프로퍼티 / 매개변수 데코레이터를 제공하며 각 상황에 맞게 데코레이터 함수에 매개변수를 넣어 주고 있었습니다.

// 메소드 데코레이터 예시
function deco(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
  console.log('데코레이터가 평가됨');
}

class TestClass {
  @deco
  test() {
    console.log('함수 호출됨')
  }
}

// 실행 결과
데코레이터가 평가됨
함수 호출됨

그런데 Typescript5.0의 데코레이터는 아래와 같이 다른 형식으로 구현되어 있습니다.

function loggedMethod(originalMethod: any, context: ClassMethodDecoratorContext) {
    const methodName = String(context.name);

    function replacementMethod(this: any, ...args: any[]) {
        console.log(`LOG: Entering method '${methodName}'.`)
        const result = originalMethod.call(this, ...args);
        console.log(`LOG: Exiting method '${methodName}'.`)
        return result;
    }

    return replacementMethod;
}

기존 PropertyDescriptor에는 이런 값들이 들어있었습니다.

interface PropertyDescriptor {
  configurable?: boolean;
  enumerable?: boolean;
  value?: any;
  writable?: boolean;
  get?(): any;
  set?(v: any): void;

그런데 새로 만들어진 ClassMethodDecoratorContext 에는 final 여부, 메소드 이름 등 간단한 값만 들어있고 PropertyDescriptor에서 제공하는 여러 값들은 더 이상 제공하지 않게 되었습니다.

PropertyDescriptor를 사용하여 유저 입력 데이터의 글자수 / 정규식 검증 등을 진행하고 있는 NestJS 에게는 큰 일이 발생해버렸죠. 애초에 인터페이스도 안맞아서 쓸 수도 없었구요.

그래서 Typescript 5.0은 못 쓰는 건가요?

다행히 --experimentalDecorators 플래그를 tsconfig에서 바로 제거하지 않았고, 한동안은 제거하지 않을 것 같습니다. 그래서 기존에 Nest.js로 개발을 하시던 분들은 기존 tsconfig를 그대로 유지한 채로 Typescript 버전을 올리는 것이 가능할 것 같습니다.

TS 5.0의 Decorator는 언제쯤 적용할 수 있을까요?

이 궁금증을 해결하기 위해 Nest.js 공식 디스코드를 확인해보았습니다.


여러 내용들이 있는데요, 요약하자면 우선은 --experimentalDecorators을 그대로 유지한 채 사용하는 것을 권장하고 있습니다.
그리고 조금씩 작업을 하고 있다고는 합니다. 언제 다 끝날지는 모르겠네요😂

결론 정리

Typescript 5.0에서 정식으로 도입된 Decorator 기능! 하지만 기존 실험적 기능을 통해 제공되던 Decorator의 구현과 많은 부분이 달라져서, NestJS 등 기존 Decorator를 사용하던 많은 프레임워크들과 라이브러리들에게 큰 숙제를 안겨준 것 같습니다.

하지만 우리는 언제나 고쳐나가겠죠? 늘 그랬던 것 처럼요👩‍💻

profile
복잡한 세상 편하게 살자

0개의 댓글