본문 바로가기

javascript/typescript

[타입스크립트] sequelize: Optional 인터페이스

 

Documentation - Utility Types

Types which are globally included in TypeScript

www.typescriptlang.org

 타입스크립트에서는 일반적인 타입 변환을 용이하게 하려는 목적으로 여러가지 유틸리티 타입을 제공한다. 그러나 아쉽게도 해당 유틸리티 타입 중에서 객체 혹은 클래스 내의 "특정" 프로퍼티만을 optional 하게 만드는 유틸리티 타입은 존재하지 않는다. 이때 sequelize 라이브러리를 타입스크립트에 적용시키기 위해 여러 문서를 찾아보던 도중, 해당 라이브러리 내에 특정 프로퍼티만을 optional하게 만들어주는 Optional 인터페이스가 존재해, 이에 대해 살펴보았다.


상황 가정 : Product에 대한 인터페이스를 생성

 회사에서 특정 제품을 ( ID, 이름, 이미지 섬네일 주소, 가격, 설명 ) 라는 요소로 관리된다고 가정하자. 이 경우, 제품에 대한 인터페이스 IProduct 및 테이블 product는 다음과 같이 작성될 수 있다.

 현재 상황에서 IProduct 인터페이스는 product 테이블에 대한 일종의 ORM 처럼 동작한다. 이때 product 테이블의 id는 AUTO_INCREMENT 한정자가 설정되어 있으므로, 사용자가 따로 값을 설정하지 못한다. 따라서 실제 사용자 입장에서도 해당 값은 설정하지 못하도록 막아버리는 것이 나을 수 있다. 이 경우 Omit 유틸리티 타입을 사용할 수 있다.

Omit 유틸리티 타입을 이용, Product에서 id 프로퍼티를 제외한 IProductInput 인터페이스를 만들었다.

 그런데 때때로 데이터를 받을 때 id을 이용한다면 어떨까? 이 경우 Omit을 사용해 id 프로퍼티를 제외하는 대신, id 프로퍼티를 optional 하게 만들어야 한다. 그런데 타입스크립트에서 제공하는 유틸리티 타입 중 일부만을 선택적으로 만들어주는 타입은 존재하지 않는다. 따라서, 해당 타입이 필요하다면 직접 정의할 필요가 있다.

 Sequelize 라이브러리에 포함된 Optional 인터페이스는 해당 문제를 다음과 같이 해결한다.

  1. 선택적으로 만들고 싶은 일부 프로퍼티를 Pick 유틸리티 타입을 이용하여 추출한다.
  2. 추출된 타입에 대해 Partial 유틸리티 타입을 적용한다.
  3. 선택적으로 만들었던 프로퍼티만을 Omit 유틸리티 타입을 이용하여 제거한 타입을 만든다.
  4. 위에서 Partial 및 Omit을 적용하여 생성한 타입을 & 연산자를 이용하여 합친다.

 위 작업을 거치면 일부 프로퍼티가 optional하게 바뀐 타입 및 해당 프로퍼티만을 제외한 타입을 결합한 새로운 타입이 만들어지는데, 이 행위는 우리가 요구한 일부 프로퍼티만을 선택적으로 만드는 동작과 일치한다.

Optional 타입을 적용한 ProductInput 클래스는 다음과 같이 나타난다.

우리가 원하는대로 id 프로퍼티가 선택적으로 나타나고 있는 모습을 볼 수 있다.


결론

 Sequelize 라이브러리에서 제공하는 Optional 인터페이스는 Partial, Omit, Pick 등의 유틸리티 타입을 조합하여 만든 것으로, 선택된 특정 프로퍼티를 선택적으로 만들 수 있다. 

 해당 인터페이스를 분석하면서, 내가 생각하는 기능을 이미 있는 기능을 중심으로 분리해서 파악하고, 해당 기능들을 이용하여 생성할 수도 있다는 것을 느꼈다. 좀 더 생각의 폭을 넓힐 필요가 있음을 실감한다.