본문 바로가기
FrontEnd/JavaScript

[ JavaScript ] JSDoc : Providing Type Hints in JS via JSDoc

by ウリ김영은 2023. 10. 27.

JSDoc 이란?

자바스크립트 API 문서 생성기이다.

자바스크립트 소스코드에 JSDoc 형식의 주석을 추가하면 API를 설명하는 HTML 문서를 생성할 수 있다.

JSDoc 주석은 /\*\* ... \*/\ 사이에 기술한다. (일반적인 /\* ... \*/\ 는 무시된다.)

파일 맨 위에 //@ts-check 추가해준다.

//@ts-check

Types

@type

type can be primitive, declared in a TS declaration, declared in a JSDoc @typedef

// @ts-check

/** @type {string} */
const string;

/** @type {number} */
const number;

/** @type {boolean} */
const boolean;

/** @type {*} */
const any;

/** @type {?} */
const unknown;

/** @type {number[], Array.<number>, Array<number>} */
const numbersArr;

/** @type { {id: number, content: string, completed: boolean} } */
const object;

//A map-like object that maps arbitrary `string` properties to `number`s
//same as ts types {[x:string]:number}
/** @type {Object.<string,number>}
const stringToNumber

/** @type {string|number} */
const union;

/** @type {Array<{ id: number, content: string, completed: boolean }>} */
const generic

/** @type {Window} */
const window;

/** @type {Promise<string>} */
const promisedString

/** @type {HTMLElement} */
const myElement = document.querySelector(selector)

/** @type {function(string, boolean): number} Closure syntax */
/** @type {(s: string, b: boolean) => number} TypeScript syntax */
/** @type {Function} */
function () {}

Casts

괄호 안 표현 앞에 @type 태그를 추가해서 타입을 더해줄 수 있다.

타입스크립트처럼 const 에도 추가할 수 있다.

var typeAssertedNumber = /** @type {number} */ (numberOrString);

let one = /** @type {const} */(1);

Import types

  • import types 를 사용해서 다른 파일에서 선언문을 가져올 수 있다.
  • syntax is TS-specific and differs from the JSDoc standard
  • can be used to get the type fo a value from a module
// @filename: types.d.ts
export type Pet = {
  name: string,
};

// @filename: main.js
/**
 * @param {import("./types").Pet} p
 */
function walk(p) {
  console.log(`Walking ${p.name}...`);
}

/**
 * @type {typeof import("./accounts").userAccount}
 */
var x = require("./accounts").userAccount;

@param / @arg / @argument & @ returns / @return

  • @param은 @type 과 동일하게 사용가능하고,매개변수 이름을 대괄호로 감싸서 선택적 매개변수임을 명시할 수 있다.
  • 매개변수 이름을 추가할 수 있고,
  • @return은 함수의 리턴 타입에 쓰인다.
// Parameters may be declared in a variety of syntactic forms
/**
 * @param {string}  p1 - A string param.
 * @param {string=} p2 - An optional param (Google Closure syntax)
 * @param {string} [p3] - Another optional param (JSDoc syntax).
 * @param {string} [p4="test"] - An optional param with a default value
 * @returns {string} This is the result
 */
function stringsStringStrings(p1, p2, p3, p4) {
  // TODO
}

/**
 * @return {PromiseLike<string>}
 */
function ps() {}

/**
 * @returns {{ a: string, b: number }} - May use '@returns' as well as '@return'
 */
function ab() {}

@typedef

  • 복잡한 타입을 정의내릴 수 있다. @param 과 문법이 비슷하다.
  • 첫번째 줄에 object 라고 써도 되고, Object 라고 써도 된다.
/**
 * @typedef {Object} SpecialType - creates a new type named 'SpecialType'
 * @property {string} prop1 - a string property of SpecialType
 * @property {number} prop2 - a number property of SpecialType
 * @property {number=} prop3 - an optional number property of SpecialType
 * @prop {number} [prop4] - an optional number property of SpecialType
 * @prop {number} [prop5=42] - an optional number property of SpecialType with default
 */

/** @type {SpecialType} */
var specialTypeObject;

@callback

  • @typedef 와 비슷하지만 객체가 아니라 함수 타입을 정의한다.
  • 물론 @typedef 로도 표현가능하다.
/**
 * @callback Predicate
 * @param {string} data
 * @param {number} [index]
 * @returns {boolean}
 */

/** @type {Predicate} */
const ok = (s) => !(s.length % 2);

/** @typedef {(data: string, index?: number) => boolean} Predicate */

@template

  • can declare type parameters
  • lets you make functions, classes, or types that are generic

@satisfies

  • is used to declare that a value implements a type but does not affect the type of the value

// @ts-check
/**
 * @typedef {"hello world" | "Hello, world"} WelcomeMessage
 */

/** @satisfies {WelcomeMessage} */
const message = "hello world"

const message: "hello world"

//Type '"Hello world!"' does not satisfy the expected type 'WelcomeMessage'.
const failingMessage = "Hello world!"

Classes

  • can be declared as constructor functions; use @constructor along with @this

Property Modifiers

@public & @private & @protected (TS의 public, private, protected 와 동일)

  • @public : property can be reached from anywhere
  • @private : property can only be used within the containing class
  • @protected : property can only be used within the containing class , and all derived subclasses, but not on dissimilar instances of the containing class.
// @ts-check

class Car {
  constructor() {
    /** @private */
    this.identifier = 100;
  }

  printIdentifier() {
    console.log(this.identifier);
  }
}

const c = new Car();
console.log(c.identifier); // Property 'identifier' is private and only accessible within class 'Car'.

@readonly

  • ensures that a property is only ever written to during initialization

@override

  • 타입스크립트와 동일하게 동작한다.
  • 베이스 클래스의 메소드를 덮어 쓰는 메소드에 쓴다.

@extends / @augments

  • @extends 는 클래스와만 동작한다.
/**
 * @template T
 * @extends {Set<T>}
 */
class SortableSet extends Set {
  // ...
}

@implements

  • there is no JS syntax for implementing a TS interface

@class / @constructor

@this

  • compiler can usually figure out the type of this by context
  • if no context, can explicitly specify the type of this with @this
/**
 * @this {HTMLElement}
 * @param {*} e
 */
function callbackForLater(e) {
  this.clientHeight = parseInt(e); // should be fine!
}

Documentation

@deprecated

@see

  • lets you link to other names in your programs

@link

  • similar to @see
  • it can be used inside other tags (@see can't)
type Box<T> = { t: T }
/** @returns A {@link Box} containing the parameter. */
function box<U>(u: U): Box<U> {
  return { t: u };
}

Other

@enum

  • allows you to create an object literal whose members are all of a specified type
  • TS 와 다르게 any type 을 가질 수 있다
/** @enum {number} */
const JSDocState = {
  BeginningOfLine: 0,
  SawAsterisk: 1,
  SavingComments: 2,
};

JSDocState.SawAsterisk;

@author

  • can specify the author
    /**
    * Welcome to awesome.ts
    * @author Ian Awesome <i.am.awesome@example.com>
    */

참조

https://poiemaweb.com/jsdoc-type-hint

https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html

https://jsdoc.app/