compilerOptions의 lib 속성은 합쳐진 라이브러리의 정의 파일(declaration files)을 특정해주는 역할을 하고, 그 정의 파일의 목표로 하는 런타임 환경(실행 환경)을 나타낸다.
즉, lib 속성은 타입스크립트에게 내가 어떤 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 속성에 DOM을 안 넣어도 된다.
타입스크립트는 내장된 자바스크립트 API를 위한 기본적인 타입 정의는 가지고 있다.
이 말은, 누군가 시간 들여서 타입스크립트에게 localStorage나 document 등의 구조, 인자, 리턴 값과 리턴 타입을 설명해줬다는 뜻이다.
누군가 타입을 설명해 둔 그 파일이 타입 정의(type definition)이다.
타입 정의는 타입스크립트에게 몇몇 자바스크립트 코드와 API의 타입을 설명할 수 있도록 한다.우리는 타입스크립트에게 다양한 것들의 타입에 대해 소통해야 한다. 문제는 대부분의 경우 우리가 다른 패키지나, 프레임워크, 라이브러리를 사용하는데, 그것들이 타입스크립트로 만들어 진게 아니라 자바스크립트로 만들어 졌다는 것이다.
그래서 JS로 만들어진 라이브러리를 TS 프로젝트에 사용하려고 하면 타입스크립트는 그것들의 타입을 알 수 없다.
타입스크립트는 JS코드를 사용할 수 있게 해준다. 그래서 ts파일에 JS코드를 써도 작동 한다. 그런데 우리가 타입스크립트의 자동 완성 기능, 즉 타입에 따라 오류 띄워주는 그 꿀 기능을 사용하고자 한다면!! 타입 정의가 필요하다. 즉, 누군가 공들여 쓴 타입 정의 파일이 있어야 그 기능을 사용할 수 있다.
우리가 자바스크립트로 만들어진 패키지나 라이브러리를 사용하게 될텐데, 이를 타입스크립트에게 설명하려면 타입 정의가 필요한 것이다.
그래야 타입스크립트가 우릴 도와줄 수 있다. 타입스크립트 도움 받으려고 타입스크립트 쓰는거니까..😇
모듈인지, 파일인지에 따라 두 가지 방법이 있다.init(), exit() 두 함수를 가진 /src/myPackage.js파일을 만들고 index.ts 파일로 가서 myPackage가 node의 모듈인 것처럼 행동해 보자.
export function init(config) {
return true;
}
export function exit(code) {
return code + 1;
}
이런 패키지가 있다고 가정하고 이 패키지를 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에서 타입과 콜 시그니처를 정의하고 있기 때문에 자동 완성 기능을 사용할 수 있다.
/src/myPackage.d.ts 파일을 생성하고, 콜 시그니처와 타입을 정의하면 된다.//Config 인터페이스
interface Config {
url: string;
}
//모듈 선언
declare module "myPackage" {
//여기선 함수를 구현하지는 않음! 호출 시그니처만 작성하면 된다.
function init(config: Config): boolean;
function exit(code: number): number;
}


하지만 직접 이렇게 타입 정의 파일을 만들 일은 별로 없을거다 ^^~
오히려 자주 맞닥뜨릴 수 있는 경우는 프로젝트 안에서 자바스크립트와 타입스크립트 파일이 같이 들어 있는 경우이다.
특히 자바스크립트에서 타입스크립트로 이전하는 경우라면 더 그렇다.
자바스크립트 프로젝트를 타입스크립트 프로젝트로 이전(migration)할 때 어떤 일이 발생하는지 알아보자.
먼저 아까 작성해둔 정의 파일을 삭제한다.
그러고 나서 npm이나 node_modules에 있는 패키지 사용하는 것처럼 말고, 실제 파일에서 호출해보자.
~ from "./myPackage" 처럼 경로를 이용하여 가져오면 된다.//🔥 npm이나 node_modules에 있는 패키지 사용하는 것처럼 말고, 파일을 가져와 보자.
import { init } from "./myPackage";
init();
{ "compilerOptions": { "allowJs": true } }그러면 오류가 사라진다. 그리고 이제 타입스크립트가 js 파일 안에 있는 함수를 불러올 수 있게 된다.

그리고 타입스크립트는 그걸 해냅니다.
자바스크립트 파일에 JSDoc을 작성하여, 자바스크립트 파일도 타입스크립트의 보호를 받을 수 있다.
JSDoc은 코멘트로 이루어진 문법이다.//@ts-check 라고 쓰면 타입스크립트 파일에게 이 자바스크립트 파일을 확인하라고 알려준다.//@ts-check
export function init(config) {
return true;
}
export function exit(code) {
return code + 1;
}
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;
}

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