[TypeScript] tsconfig.json_compilerOptions의 lib 속성 자세히 보기

summereuna🐥·2023년 9월 5일

TypeScript

목록 보기
12/13

compilerOptions의 lib 속성은 합쳐진 라이브러리의 정의 파일(declaration files)을 특정해주는 역할을 하고, 그 정의 파일의 목표로 하는 런타임 환경(실행 환경)을 나타낸다.


1. 목표로 하는 런타임 환경을 나타냄


즉, lib 속성은 타입스크립트에게 내가 어떤 api를 사용하고 어떤 환경에서 코드를 실행할지 알려주는 속성이다.

  • 어떤 환경인지 즉, 자바스크립트의 어떤 버전이 그 환경에서 사용되는지 알려준다.
  • 그리고 동작하는 환경에 따라, 타입스크립트는 기본적으로 api의 타입을 알기 때문에 우리에게 타입을 알려준다.
  • { "compilerOptions": { "lib": ["ES6"] } }

예시

테스트를 위해 우리 코드가 es6를 지원하는 환경과, 브라우저 환경에서도 실행될거라고 지정해보자.

  • { "compilerOptions": { "lib": ["ES6", "DOM"] } }

  • 브라우저 환경 DOM을 lib에 포함하면, 타입스크립트에게 이 ts 코드가 브라우저를 위해 작성된다고 알려주는 것이다.

타입스크립트 코드에서 document를 쓰면, 타입스크립트는 document가 가지고 있는 모든 이벤트와 메서드를 자동 완성 기능을 사용하여 보여준다.

  • document.querySelector() 이런식으로 쓸 수 있도 타입설명도 볼 수 있다.
  • 그리고 command 버튼 누른 상태로 querySelector를 클릭하면 node_modules/typescript/lib안에 있는 파일인 lib.dom.d.ts파일로 이동하는데, 거기서 querySeletor의 call signature와 비슷하게 생긴 것들을 볼 수 있다.

localStorage.getItem() 을 작성하면 이렇게 마우스를 가져다 대면 타입스크립트의 콜 시그니처를 볼 수 있다.

  • 이 처럼 타입스크립트는 모든 자동 완성 기능을 우리에게 제공하여 우리를 도와 준다. 왜냐하면 타입스크립트는 브라우저의 api와 타입들을 알고 있기 때문이다.

이처럼 lib에 원하는 환경을 넣으면, 타입스크립트에게 코드가 어디서 동작해야하는 지를 알려 줄 수 있다.

그러면 타입스크립트는 내가 무엇을 사용할지 알게 되고, 타입스크립트는 사용할api가 뭔지 알게되므로 타입스크립트가 지원하는 자동 완성 기능을 사용할 수 있게 된다.

  • 브라우저 환경 DOM을 빼면, ts파일에서 document를 적어봐도 자동완성기능도 안뜨고 타입스크립트는 다큐먼트의 타입을 모른다.

서버에서만 사용하는 코드라면 lib 속성에 DOM을 안 넣어도 된다.


2. 정의 파일(declaration files)을 특정해 줌


타입스크립트는 어떻게 api의 타입을 알까?

타입스크립트는 내장된 자바스크립트 API를 위한 기본적인 타입 정의는 가지고 있다.

이 말은, 누군가 시간 들여서 타입스크립트에게 localStorage나 document 등의 구조, 인자, 리턴 값과 리턴 타입을 설명해줬다는 뜻이다.
누군가 타입을 설명해 둔 그 파일이 타입 정의(type definition)이다.

  • 타입 정의는 타입스크립트에게 몇몇 자바스크립트 코드와 API의 타입을 설명할 수 있도록 한다.

타입정의를 써야 하는 이유는 타입스크립트를 사용하는 목적과 연결되어 있다.

  • 우리는 타입스크립트에게 다양한 것들의 타입에 대해 소통해야 한다. 문제는 대부분의 경우 우리가 다른 패키지나, 프레임워크, 라이브러리를 사용하는데, 그것들이 타입스크립트로 만들어 진게 아니라 자바스크립트로 만들어 졌다는 것이다.

  • 그래서 JS로 만들어진 라이브러리를 TS 프로젝트에 사용하려고 하면 타입스크립트는 그것들의 타입을 알 수 없다.

  • 타입스크립트는 JS코드를 사용할 수 있게 해준다. 그래서 ts파일에 JS코드를 써도 작동 한다. 그런데 우리가 타입스크립트의 자동 완성 기능, 즉 타입에 따라 오류 띄워주는 그 꿀 기능을 사용하고자 한다면!! 타입 정의가 필요하다. 즉, 누군가 공들여 쓴 타입 정의 파일이 있어야 그 기능을 사용할 수 있다.

  • 우리가 자바스크립트로 만들어진 패키지나 라이브러리를 사용하게 될텐데, 이를 타입스크립트에게 설명하려면 타입 정의가 필요한 것이다.
    그래야 타입스크립트가 우릴 도와줄 수 있다. 타입스크립트 도움 받으려고 타입스크립트 쓰는거니까..😇

자바스크립트 ✅모듈과 ✅파일을 위한 타입 정의 방법

그렇다면 타입 정의 파일을 어떻게 작성할까?

  • 자바스크립트 모듈인지, 파일인지에 따라 두 가지 방법이 있다.

1. node_modules에 설치된 자바스크립트 ✅모듈을 타입스크립트에서 사용하는 방법: 타입 정의 파일 생성하기


npm으로부터 자바스크립트 패키지를 받아올 때, 타입스크립트에서 어떻게 JS 패키지를 사용할 수 있는지 알아보기 위해, 아래의 상황을 가정해 보자.

init(), exit() 두 함수를 가진 /src/myPackage.js파일을 만들고 index.ts 파일로 가서 myPackagenode의 모듈인 것처럼 행동해 보자.

📍 myPackage 모듈

export function init(config) {
  return true;
}

export function exit(code) {
  return code + 1;
}

이런 패키지가 있다고 가정하고 이 패키지를 index.ts 파일에 임포트해서 사용한다고 해보자.

📍 /src/index.ts

//🔥 npm이나 node_modules에 있는 패키지 사용하는 것처럼 해보자.
//from "myPackage" 에서 가져오면 됨
import { init } from "myPackage";
//모듈이 선언되지 않았기 때문에 아에 가져올 수가 없다.

//그런데 init() 쓰면 작동하는 것처럼 되버린다.
init();

왜냐면 타입스크립트가 strict 모드로 설정되지 않았기 때문에 이런걸 보호해줄 수가 없다.
스트릭트모드 트루로 해주면 타입스크립트는 모든 실수를 보호해주려고 한다.

strict 모드 true로 설정하여 타입스크립트 보호 기능 켜자.

//📍 tsconfig.json

{
  "include": ["src"],
  "compilerOptions": {
    "outDir": "build",
    "target": "ES6",
    "lib": ["ES6", "DOM"],
    "strict": true //🔥 추가해주기
  }
}

그럼 이제 오류를 알려주기 시작한다.

  • 정의 파일을 찾을 수 없다고 오류가 뜬다.

  • 정의 파일은 자바스크립트 코드의 모양을 타입스크립트에게 설명해주는 파일이다. 정의 파일인 d.ts에서 타입콜 시그니처를 정의하고 있기 때문에 자동 완성 기능을 사용할 수 있다.

직접 만든 패키지이기 때문에 정의 파일이 없다. 타입스크립트에게 직접 myPackage에 대해 설명해주기 위해서 정의 파일을 만들어 보자.

  • /src/myPackage.d.ts 파일을 생성하고, 콜 시그니처타입을 정의하면 된다.

📍 /src/myPackage.d.ts

//Config 인터페이스
interface Config {
  url: string;
}

//모듈 선언
declare module "myPackage" {
  //여기선 함수를 구현하지는 않음! 호출 시그니처만 작성하면 된다.
  function init(config: Config): boolean;
  function exit(code: number): number;
}

  • myPackage에 대한 모듈이 선언되었기 때문에 index.ts에서 임포트할 수 있게 된다.
  • 그리고 init, exit 함수의 콜 시그니처를 작성하여 타입스크립트에게 이 함수들의 타입을 알려주었기 때문에, 타입스크립트는 자동 완성 기능으로 우릴 도와줄 수 있게 된다.

  • 이런식으로 함수에 대한 설명도 써 둘 수 있다.

만약 npm 파일이나 프로젝트를 다운 받았는데, 타입이 없어서 타입스크립트의 도움을 받을 수 없다면 이렇게 타입 정의 파일을 만들 수 있다.

  • 하지만 직접 이렇게 타입 정의 파일을 만들 일은 별로 없을거다 ^^~

  • 오히려 자주 맞닥뜨릴 수 있는 경우는 프로젝트 안에서 자바스크립트와 타입스크립트 파일이 같이 들어 있는 경우이다.

  • 특히 자바스크립트에서 타입스크립트로 이전하는 경우라면 더 그렇다.


2. 자바스크립트 ✅파일을 타입스크립트에서 사용하는 방법: JSDoc 사용하기


자바스크립트 프로젝트를 타입스크립트 프로젝트로 이전(migration)할 때 어떤 일이 발생하는지 알아보자.

먼저 아까 작성해둔 정의 파일을 삭제한다.
그러고 나서 npm이나 node_modules에 있는 패키지 사용하는 것처럼 말고, 실제 파일에서 호출해보자.

  • 파일을 임포트하려면 ~ from "./myPackage" 처럼 경로를 이용하여 가져오면 된다.
//🔥 npm이나 node_modules에 있는 패키지 사용하는 것처럼 말고, 파일을 가져와 보자.
import { init } from "./myPackage";

init();

js 파일을 가져오려면 tsconfig.json 파일에서 allowJs옵션을 true로 더해줘야 한다.

  • { "compilerOptions": { "allowJs": true } }
    이 속성은 타입스크립트 안에서 자바스크립트를 허용할지 말지 결정한다.

그러면 오류가 사라진다. 그리고 이제 타입스크립트가 js 파일 안에 있는 함수를 불러올 수 있게 된다.

  • js파일에 함수를 정의해 뒀기 때문에 타입스크립트가 추론은 하지만, 정의된 타입이 없기 때문에 any로 뜬다.

이런식으로 js파일과 ts파일을 섞어서 프로젝트를 진행해도 괜찮다.

  • 옛날 코드는 js파일 그대로 두고, 새로 작성하는 파일만 ts파일로 만든다던가 말이다.
  • ts파일이 js파일을 확인도 하고 싶고, 완전히 타입스크립트로 이전하고 싶지는 않다면, 이렇게 해도 된다.
  • 코드가 엄청 많다면 js 파일 그대로 두고 타입스크립트 보호를 좀 받고 싶을 수 있다.

그리고 타입스크립트는 그걸 해냅니다.

📝 js 파일이 타입스크립트의 보호를 받는 방법: JSDoc

JSDoc

자바스크립트 파일에 JSDoc을 작성하여, 자바스크립트 파일도 타입스크립트의 보호를 받을 수 있다.

  • JSDoc은 코멘트로 이루어진 문법이다.
  • 함수 바로 위에 코멘트를 작성하면, 타입스크립트가 그 코멘트를 읽을 수 있다.
  • 자바스크립트 파일에서 함수 위에 //@ts-check 라고 쓰면 타입스크립트 파일에게 이 자바스크립트 파일을 확인하라고 알려준다.

📍 /src/myPackage.js

//@ts-check

export function init(config) {
  return true;
}

export function exit(code) {
  return code + 1;
}

JSDoc 코멘트로 타입 도움 받기

ts파일에서 타입을 지정하는 것 처럼 js 파일에서도 쓰기 원한다면 다음과 같이 작성하면 된다.

//@ts-check

/**
 * 프로젝트를 초기화 한다.
 * @param {object} config
 * @param {boolean} config.debug
 * @param {string} config.url
 * @returns boolean
 */
export function init(config) {
  return true;
}

/**
 * 프로그램을 종료한다.
 * @param {number} code
 * @returns number
 */
export function exit(code) {
  return code + 1;
}

  • 그러면 타입스크립트 코드를 사용하지 않고도 코멘트를 통해서도 도움을 받을 수 있다.
    타입스크립트가 이 코멘트를 읽고 도와준다.

만약에 이 코드를 실제 웹사이트나 서버의 프로덕션 환경에서 사용 중이라면 당장 코드에서 에러날 걱증은 안해도 된다. 코드에 코멘트만 더했을 뿐이기 때문이다.

profile
Always have hope🍀 & constant passion🔥

0개의 댓글