jsdoc 사용하기

GJ·2022년 2월 15일
1

jsdoc

자바스크립트로 개발하다보면 자바나 C++같은 언어처럼 타입 힌팅이 되거나 코드 인텔리전스가 되었으면 하는 경우가 있다.
최근에 타입스크립트가 사용되면서 이런 문제가 많이 해결되었지만, 아직 많은 프로젝트는 자바스크립트로 작성되어 있고, 이를 위해서 타입스크립트로 전환하는 것도 만만치 않은 일이다.
그래서 타입스크립트까지는 사용하지 않고 ide에서 타입 힌팅과 코드 인텔리전스를 이용하는 방법이 있는데 그 방법이 jsdoc이다.
타입스크립트가 사용되기 이전에는 jsdoc으로 주로 타입 힌팅을 하였다.

타입스크립트와의 차이

jsdoc은 자바스크립트에 바로 적용할 수 있다.
타입스크립트는 코드내에 직접 타입을 선언하고 후에 트랜스파일러로 타입관련 코드를 삭제하여 자바스크립트로 변환하고 실행을 진행한다면, jsdoc은 주석 내부에 특정한 형식으로 타입을 선언한다.
jsdoc은 주석이기 때문에 타입에러가 난다고 해서 타입스크립트처럼 트랜스파일중에 에러를 뱉고 뻗어버리는것은 아니고, 그냥 타입 힌팅과 코드 인텔리전스만 정상적으로 작동하지 않는다.
그 외에는 세부적인 설정을 제외하고 타입스크립트와 전체적인 아이디어는 비슷하다.
그래서 타입스크립트나 jsdoc중에 하나를 알고 있으면 다른 쪽을 사용하는것은 전혀 문제가 되지 않을 것 같다.

사용방법

타입선언

/**
 * @type {number}
 */
let num

위와 같이 주석을 작성하고 @type 어노테이션 뒤에 자료형을 넣어주면 된다.
타입스크립트와 다른 점은 변수명 오른쪽이 아닌 바로 위에 써준다는 정도다.

커스텀타입정의 및 선언

/**
 * @typedef {string} StringType
 */
/**
 * @type {StringType}
 */
const statement

string, number, boolean등과 같은 원시 자료형이 아닌 내가 정의하고 싶은 타입을 선언하고 싶다면 typedef를 사용하여 타입을 만들고 타입을 선언해주면 된다.
타입을 정해주어야 하는 다른 언어들과 다르게 jsdoc은 변수 앞에 중괄호로 타입을 요구한다.

객체타입정의 및 선언

/**
 * @typedef {Object} Person
 * @property {string} name
 * @property {number} age
 * @property {boolean} isStudent
 */
/**
 * @type {Person}
 */
const Person1

객체에 대한 타입을 정의하고 싶다면 Object 타입을 정의하고
그 아래로 property들을 적어주면 된다.
(object를 사용해도 되는데 Object라고 써야 동적 키를 가진 값을 정의할 수 있다.)
각각의 property들에 대한 타입도 typedef와 같은 방식으로 적어주면 된다.

함수인터페이스정의

/**
 * 입력된 변수 a와 b를 합한 결과를 얻을 수 있는 함수 입니다.
 * @param {number} a
 * @param {number} b
 * @return {number}
 */
const sum = (a, b) => {return a+b}

어노테이션 없이 내용을 입력하면 함수에 마우스 오버를 했을 때 이 함수에 대한 설명을 볼 수 있다.
param 어노테이션을 사용하여 각각의 파라미터에 대해 형식을 지정할 수 있다.
return 어노테이션을 사용하여 리턴값의 형식도 지정할 수 있다.
리턴값이니까 당연히 변수명을 써줄 필요는 없다.

or

/**
 * @type {number | string}
 */
let numOrString

여러가지 형식이 될 수 있는 변수라면 타입스크립트와 같이 |를 사용하면 된다.

enum

/**
 * @enum {string}
 */
const example = {
  JAN: 'january',
  FEB: 'feburary',
  MAR: 'march',
};

enum은 타입스크립트랑 좀 다른데, 실제 객체를 선언해서 이 객체가 enum이다~ 라고 알려주는 형식이다.
개인적으로 타입스크립트에서의 enum보다는 이게 더 직관적인것 같다.

동적키를 가지는 객체타입정의

/**
 * @typedef {Object<string, string>} Person
 */
/**
 * @type {Person}
 */
const Person1

변수명이 정해지지 않았지만 키와 값의 형식은 정해져있다면 위와 같이 키와 값의 형태를 적어주면 된다.

generic & 외부라이브러리타입

/**
 * @param {requestLoginTokenInput} input
 * @return {Promise<import('axios').AxiosResponse<requestLoginTokenOutput>>}
 */
export const requestLoginToken = (input) => {
  ...
  return axios.post(`/login`, data);
};

꺽쇠안에 타입을 써주면 제네릭도 사용가능하다.
심지어 외부라이브러리에서 타입을 가져올수도 있다.
(code intellisense로 찾아보면 거진 다 나온다.)

타입스크립트처럼 사용하기

/**
 * @type {{[key: string]: string}} Person2
 */
const Person2

이건 개인적으로 알아낸건데,
충격적이게도 타입스크립트처럼 타입정의도 가능하다.

결론

솔직히 타입스크립트랑 거의 비슷해서 어렵지 않았다.
개인적으로는 신규 개발할때는 타입스크립트를 적용하되 기존 프로젝트는 jsdoc으로도 충분한것 같다.
eslint에 jsdoc을 무조건 따르게 하는 config도 있기 때문에 유사 타입스크립트처럼 사용할 수도 있다.

참고할만한 사이트

https://typescript-kr.github.io/pages/jsdoc-reference.html
https://jsdoc.app/

profile
Frontend Developer

0개의 댓글