타입 힌팅 개요

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;
}
선택적 매개변수

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

/**
 * 숫자 두 개를 더합니다
 * @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(/* ... */);

참고: import()기본 JSDoc 구문이 아닙니다, 그러나 많은 IDE 및 도구에서 인식됩니다. 이 경우 코드의 명확성과 IDE를 통한 향상된 개발자 경험을 위해 더 나은 명확성을 추구합니다.

JSDoc은 제한적

앞에서 말했듯이, JSDoc은 어휘가 제한적입니다. 그리고 사용하면 유형을 완전히 설명할 수 없을 수 있습니다. 그러나 때로는 유형 추론을 위해 타사 라이브러리의 유형 정의를 사용할 수 있습니다. 이러한 접근 방식의 예는 다음과 같습니다:

- 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의 구문을 사용하여 함수에 설명을 추가할 수 있습니다. 예를 들어:

/** 컴포넌트를 마운트하고 해당 컴포넌트에 대한 확장된 Wrapper를 반환합니다 */
export const mountExtended = compose(extendedWrapper, mount);

시스템 요구 사항

IDE 및 도구에서 GitLab 코드베이스 및 타사 패키지의 유형 정의가 올바르게 표시되도록하려면 설정이 필요할 수 있습니다.

VS Code 설정

VS Code IntelliSense가 작동하지 않는 경우 TS 서버가 사용할 수있는 메모리 양을 늘려야 할 수 있습니다. 이를 위해 settings.json 파일에 다음을 추가하십시오:

{
    "typescript.tsserver.maxTsServerMemory": 8192,
    "typescript.tsserver.nodePath": "node"
}

별칭

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

GitLab 프로젝트에는 웹팩 구성 및 현재 환경 변수를 기반으로 jsconfig.json 파일을 생성 또는 업데이트하는 스크립트가 있습니다. GitLab 프로젝트 루트에서 다음을 실행하여 jsconfig.json 파일을 생성 또는 업데이트하십시오:

node scripts/frontend/create_jsconfig.js

jsconfig.json은 gitignore 목록에 추가되어 있으므로 GitLab 프로젝트에서 원격 저장소로 프로젝트 변경 사항이 발생하지 않습니다. 또한 Git 풀에서 제외되므로 수동으로 생성 또는 업데이트해야 합니다.

서드 파티 TypeScript 정의

더 많은 라이브러리가 TypeScript를 사용하여 유형 정의를 하는 가운데, 일부는 여전히 JSDoc으로 주석이 달린 유형을 가지거나 전혀 유형이 없을 수 있습니다. 이를 보완하기 위해 TypeScript 커뮤니티는 인기있는 JavaScript 라이브러리를 위한 독립적인 유형 정의를 생성하고 지원하는 DefinitelyTyped 이니셔티브를 시작했습니다. 이러한 정의를 사용하려면 유형 패키지를 명시적으로 설치(yarn add -D "@types/lodash")하거나 자동 유형 획득 (ATA)이라는 기능을 사용할 수 있습니다. ATA는 일부 언어 서비스에서(예: VS Code의 ATA) 사용할 수 있습니다.

자동 유형 획득 (ATA)은 DefinitelyTyped 목록에서 유형 정의를 자동으로 가져옵니다. 그러나 ATA가 작동하려면 전역으로 설치된 npm이 필요할 수 있습니다. IDE는 npm 실행 파일의 위치를 설정하는 대체 구성 옵션을 제공할 수 있습니다. 세부 정보는 IDE 설명서를 참조하십시오.

ATA가 항상 작동한다는 것을 보장할 수 없으며 Lodash는 우리의 유틸리티 함수 중 많은 부분을 담당하므로, Lodash를 위한 DefinitelyTyped 정의package.jsondevDependencies에 명시적으로 추가했습니다. 이를 통해 모두가 기본 제공으로 lodash 기반 기능에 대한 유형 힌트를 얻을 수 있도록 보장합니다.