Type hinting overview

GitLab 프로젝트의 프론트엔드 코드베이스는 현재 유형을 필요로 하지 않거나 강제로 적용하지 않습니다. 유형 주석은 선택사항이며, 현재 JavaScript 코드베이스에서는 유형 안전성을 강요하지 않습니다. 그러나 유형 주석은 코드베이스에 명확성을 추가하는 데 매우 도움이 될 수 있으며, 특히 공유 유틸리티 코드에서 유용합니다. 본 문서는 현재 유형 힌팅이 어떻게 작동하는지, 새 유형 주석을 추가하는 방법 및 GitLab 프로젝트에서 유형 힌팅을 설정하는 방법을 다루고 있습니다.

JSDoc

JSDoc은 특별히 형성된 주석을 사용하여 JavaScript 코드의 유형을 문서화하고 설명하는 도구입니다. JSDoc의 유형 어휘는 비교적 제한적이지만 많은 IDE들에서 널리 지원됩니다.

예시

함수 설명

@param@returns를 사용하여 함수 유형을 설명합니다:

/**
 * 두 숫자를 더함
 * @param {number} a 첫 번째 숫자
 * @param {number} b 두 번째 숫자
 * @returns {number} 두 숫자의 합
 */
function add(a, b) {
    return a + b;
}
선택적 매개변수

매개변수 이름 주변에 대괄호 []를 사용하여 선택적으로 표시할 수 있습니다. 기본값은 [name=value] 구문을 사용하여 제공할 수 있습니다:

/**
 * 두 숫자를 더함
 * @param {number} value
 * @param {number} [increment=1] 선택적 매개변수
 * @returns {number} 두 숫자의 합
 */
function increment(a, b=1) {
    return a + b;
}
객체 매개변수

객체를 허용하는 함수는 @param 이름에서 object.field 표기법을 사용하여 유형을 지정할 수 있습니다:

/**
 * 두 숫자를 더함
 * @param {object} config
 * @param {string} config.path 경로
 * @param {string} [config.anchor] 앵커
 * @returns {string}
 */
function createUrl(config) {
    if (config.anchor) {
        return path + '#' + anchor;
    }
    return path;
}

값을 바로 지정받지 않는 변수 유형 주석

도구 및 IDE에서 값에 즉시 유형을 추론하는 것은 어려울 수 있습니다. 해당 변수에 유형을 할당하기 위해 @type 주석을 사용할 수 있습니다:

/** @type {number} */
let value;

더 많은 구문 세부 정보는 JSDoc 공식 웹사이트를 참조하세요.

JSDoc 사용 팁

기본 유형에 대문자 이름 사용

대문자 Boolean 및 소문자 boolean이 모두 허용되지만, 대개 원시형 또는 객체가 필요한 경우 소문자 버전이 올바른 선택입니다: boolean, number, string, symbol, object.

/**
 * `text`를 번역함.
 * @param {string} text - 번역할 텍스트
 * @returns {string} 번역된 텍스트
 */
const gettext = (text) => locale.gettext(ensureSingleLine(text));

잘 알려진 유형 사용

HTMLDivElement 또는 Intl과 같은 잘 알려진 유형은 사용 가능하며 직접 사용할 수 있습니다:

/** @type {HTMLDivElement} */
let element;
/**
 * 현재 로캘에 대한 Intl.DateTimeFormat 인스턴스를 생성함.
 * @param {Intl.DateTimeFormatOptions} [formatOptions] - 사용 가능한 옵션은 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat 을 참조하세요
 * @returns {Intl.DateTimeFormat}
 */
const createDateTimeFormat = (formatOptions) =>
  Intl.DateTimeFormat(getPreferredLocales(), formatOptions);

import('path/to/module')를 통한 기존 유형 정의 가져오기

다음은 즉시 정의되지 않은 Vue Test Utils Wrapper 변수의 유형을 주석으로 달아놓는 예시입니다:

/** @type {import('helpers/vue_test_utils_helper').ExtendedWrapper} */
let wrapper;
// ...
wrapper = mountExtended(/* ... */);
/** @type {import('@vue/test-utils').Wrapper} */
let wrapper;
// ...
wrapper = shallowMount(/* ... */);
note
import()원시 JSDoc 구조는 아니지만, 많은 IDE 및 도구에서 인식됩니다. 이 경우 코드의 명확성을 높이고 IDE에서 향상된 개발 경험을 제공하기 위해 사용됩니다.

JSDoc의 한계

언급했듯이, JSDoc는 어휘가 제한적입니다. 그리고 그것을 사용함으로써 유형을 완전히 설명하지 못할 수 있습니다. 그러나 때로는 3rd party 라이브러리의 유형 정의를 사용하여 코드에서 유형 추론을 도와줄 수 있습니다. 아래는 이와 같은 접근법의 예시입니다:

- export const mountExtended = (...args) => extendedWrapper(mount(...args));
+ import { compose } from 'lodash/fp';
+ export const mountExtended = compose(extendedWrapper, mount);

여기서 compose 함수의 TypeScript 유형 정의를 사용하여 mountExtended 함수에 추론된 유형 정의를 추가합니다. 이 경우 mountExtended의 매개변수는 mount의 매개변수와 동일한 유형이 될 것입니다. 또한 반환 유형은 extendedWrapper의 반환 유형과 동일할 것입니다.

그럼에도 JSDoc의 구문을 사용하여 함수에 설명을 추가할 수 있습니다. 예를 들어:

/** 컴포넌트를 마운트하고 확장된 래퍼를 반환함 */
export const mountExtended = compose(extendedWrapper, mount);

시스템 요구사항

IDEs 및 도구에서 GitLab 코드베이스 및 3rd party 패키지의 유형 정의를 올바르게 표시하려면 설정이 필요할 수 있습니다.

별칭

우리 코드베이스는 많은 별칭을 임포트에 사용합니다. 예를 들어 import Api from '~/api';app/assets/javascripts/api.js 파일을 임포트합니다. 그러나 IDEs는 그러한 별칭을 알지 못할 수 있으며 따라서 Api의 유형도 알지 못할 수 있습니다. 대부분의 IDE에서 이를 해결하려면 jsconfig.json 파일을 생성해야 할 것입니다.

GitLab 프로젝트에는 웹팩 구성 및 현재 환경 변수에 기반한 jsconfig.json 파일을 생성하는 스크립트가 있습니다. jsconfig.json 파일을 생성하거나 업데이트하려면 GitLab 프로젝트 루트에서 다음을 실행하세요:

node scripts/frontend/create_jsconfig.js

jsconfig.json은 gitignore 디렉터리에 추가되어 있으므로 GitLab 프로젝트에서의 변경이 발생하지 않습니다. 또한 Git 풀에서 제외되므로 매뉴얼으로 생성하거나 업데이트해야 합니다.

3rd party TypeScript 정의

더 많은 라이브러리가 유형 정의를 위해 TypeScript를 사용할 수 있지만, 일부는 여전히 JSDoc 주석된 유형이거나 유형이 없을 수 있습니다. 이러한 공백을 커버하기 위해 TypeScript 커뮤니티는 인기 있는 JavaScript 라이브러리를 위한 스탠드얼론 유형 정의를 생성하고 지원하는 DefinitelyTyped 이니셔티브를 시작했습니다. 이러한 정의를 사용하려면 유형 패키지를 명시적으로 설치하거나 자동 유형 획득(Automatic Type Acquisition, ATA)라는 기능을 사용할 수 있습니다. ATA는 몇몇 언어 서비스(예: VS Code의 ATA)에서 사용할 수 있습니다.

Automatic Type Acquisition(ATA)는 자동으로 DefinitelyTyped 디렉터리에서 유형 정의를 가져옵니다. 그러나 ATA가 작동하는 것은 보장되지 않으며, Lodash는 많은 유틸리티 함수에 백본으로 사용되므로 Lodash를 위한 DefinitelyTyped 정의package.jsondevDependencies에 명시적으로 추가되어 있습니다. 이는 모든 사람이 기본적으로 lodash-기반 함수에 대한 유형 힌트를 받을 수 있도록 보장합니다.