본 게시물은 이전에 운영하던 velog에서 작성됨 (2023년 2월 23일 작성)
🐨 어려운 타입스크립트
현재 nest.js로 프로젝트를 진행하고 있는데, 타입스크립트에 익숙하지 않아서 타입 지정해주는데에 많은 시간을 쏟고 있다. 이왕 타입스크립트 쓰는 김에 타입 먹일 수 있는 곳에는 다 먹이려고 하는데 쉽지가 않다.
아무튼 며칠 전부터 메소드 리턴 타입 지정을 어떻게 해야할 지 고민을 많이 했다. 다른 개발자들의 프로젝트도 좀 찾아봤는데, 둘 중 하나였다. 너무 복잡하거나(제네릭 안에 제네릭 안에 제네릭이 있다던지..) 아예 리턴 타입을 지정해주지 않는 경우였다. 뭔가 대단한 방법이 있을 줄 알았는데 딱히 그런 것도 아닌거 같아서 Response용 DTO를 만들기로 했다.
🐷 공식문서에서는
DTO는 class나 interface로 만들 수 있는데, nest.js docs에 보면 아래와 같은 설명이 있다.
we need to determine the DTO (Data Transfer Object) schema. A DTO is an object that defines how the data will be sent over the network. We could determine the DTO schema by using TypeScript interfaces, or by simple classes. Interestingly, we recommend using classes here. Why? Classes are part of the JavaScript ES6 standard, and therefore they are preserved as real entities in the compiled JavaScript. On the other hand, since TypeScript interfaces are removed during the transpilation, Nest can't refer to them at runtime.
없는 영어 실력으로 의역해보면
DTO를 만들 때 interface나 class를 사용할 수 있는데 class 사용하는 걸 추천함. 왜냐면 class는 TS에서 JS로 컴파일되어도 코드 상에도 남아있고 (나중에 메모리에도 올라서 실체가 있음). 근데 interface는 TS에서 JS로 컴파일될 때 그냥 사라짐. 그래서 런타임에 interface를 참조하고 싶어도 참조 못함
나는 이걸 보고 인터페이스를 참조할 상황이 없으면 class 대신에 interface 쓰는게 개꿀 아닌가? 라고 생각했다. DTO는 DTO대로 만들 수 있으면서 class처럼 메모리를 차지하지도 않기 때문이다.
🐱 했었는데 안됐어요
근데 바로 부작용이 나타났다.
이렇게 만든 DTO를 리턴 타입으로 설정했을 때에는 별 문제가 없었는데
DTO 내부 멤버 변수에 데코레이터를 달거나 DTO 자체를 값으로 넘겨줄 때에는 문제가 발생한다.
컴파일 타임과 런타임으로 나누어 생각해보면 타입 체크는 컴파일 타임에서 이루어지니까 별 문제가 없는 것이고 타입 체크 외의 작업은 런타임에 이루어지기 때문에 실체가 없는 인터페이스를 참조하다보니 에러가 나는 것 같다.
class로 바꿔주면 의도한대로 작동한다.
역시 공식 문서 말 듣는 게 최고인듯
'NestJS' 카테고리의 다른 글
[NestJS | Redis | Docker] 용도별로 Redis 인스턴스 만들기 (0) | 2023.07.30 |
---|---|
[NestJS] OAuth 인증 (+ 중복 로그인 방지) (0) | 2023.07.30 |
[NestJS | Redis] 데이터 캐싱하기 (Look-Aside) (0) | 2023.07.30 |
[NestJS | Redis] 세션 스토리지 만들기 (0) | 2023.07.30 |