앞에서 프로젝트를 만들 때 tsc --init 명령어로 tsconfig.json 파일을 생성했습니다. 아래와 같은 파일이 생성되었는데요. 이번 레슨에서는 이 파일에서 사용할 수 있는 옵션들에 대해서 좀 더 자세히 살펴보겠습니다.
{
"compilerOptions": {
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
"module": "commonjs", /* Specify what module code is generated. */
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
"strict": true, /* Enable all strict type-checking options. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
}
}
compilerOptions에서 사용할 수 있는 옵션 중에서 중요한 것들을 살펴보겠습니다.
타입스크립트 코드는 빌드해서 자바스크립트로 변환하는데요. 이때 변환할 자바스크립트의 버전을 정할 수 있습니다. 만약에 프로젝트가 과거 자바스크립트 표준만 지원하는 브라우저까지 지원해야 한다면, 여기서 오래된 버전을 설정할 수 있죠. 2023년 현재를 기준으로 tsconfig.json을 생성했을 때는, 기본적으로는 ES7(ES2016)으로 변환하도록 되어있습니다. 여기다가 ES6(ES2015)나 ES3 등을 설정해 줄 수 있습니다.
코드를 실행할 브라우저나 Node.js 환경에 따라 선택하시면 되는데요. 브라우저의 경우 ES5는 거의 모든 브라우저에서 지원하고, ES6는 인터넷 익스플로러를 제외하면 대부분의 브라우저에서 지원합니다. Node.js의 경우 v14 이후 버전을 쓰신다면 ES5, ES6를 대부분 지원합니다.
잘 모르겠다면 일단은 ES6로 설정해 두고 쓰시는 걸 추천드릴게요. 실행 환경에 따른 문법 지원 여부가 궁금하신 분들은 아래 두 링크를 참고해 보세요.
"ECMAScript" | Can I use... Support tables for HTML5, CSS3, etc
ECMAScript 6 compatibility table (kangax.github.io)
자바스크립트 모듈에는 크게 두 가지 방식이 있습니다. ES6부터 도입된 import/export 문법을 사용하는 ESM(ECMAScript Module) 방식이 있고요, Node.js 같은 데서 기본적으로 사용하는 CJS(CommonJS) 방식이 있는데요.
이 옵션에서는 자바스크립트 코드로 트랜스파일할 때 어떤 모듈 문법으로 변환할지 선택할 수 있습니다. 다양한 옵션 값을 지원하는데요. ESM을 쓰시려면 es6, es2020 같이 es로 시작하는 값을 쓰면 되고, CJS를 쓰시려면 commonjs라고 쓰시면 됩니다.
보통 Node.js 환경에서는 CJS를 사용하고, 프론트엔드 개발을 할 때는 보통 번들러에서 모듈을 알아서 처리해 주기 때문에 ESM, CJS 상관없이 쓰실 수 있을 겁니다. 어떤 걸 선택할지 잘 모르겠다면 commonjs로 설정하는 걸 추천드릴게요.
ESM 문법에서 import * as moment from 'moment'라든가 import moment from 'moment'라는 문법은 서로 다른데요. 이 옵션을 false로하면 CJS로 변환했을 때 두 코드는 같은 형태의 코드 const moment = require('moment')로 변환됩니다. 안전하게 모듈을 사용하려면 esModuleInterop 옵션은 true로 해놓는 것을 권장드립니다.
TypeScript: TSConfig Reference - Docs on every TSConfig option (typescriptlang.org)
macOS를 사용하시는 분들은 main.ts라는 파일과 Main.ts라는 파일이 서로 다른데요. Windows와 같이 어떤 운영체제에서는 종종 main.ts라는 파일과 Main.ts라는 파일을 동일하게 취급하기도 합니다. 이런 환경에서 개발하더라도 반드시 대소문자 구분을 명확하게 하겠다는 옵션입니다. 이 옵션도 반드시 true로 해 놓는 걸 권장드립니다.
이 옵션을 켜면 stict와 관련된 여러 규칙들을 한꺼번에 켤 수 있는데요. 어떤 옵션들이 켜지는지는 공식 문서의 strict 옵션 설명을 참고해 주세요. 여기서는 그중에서도 대표적으로 알아두면 좋은 것 두 가지를 소개해드리겠습니다.
noImplicitAny: 아무 타입을 직접 정의하지 않고, 타입 추론도 되지 않는 상태를 implicit any라고 하는데요. 쉽게 말해서 기존 자바스크립트 코드처럼 타입 없이 사용하는 걸 implicit any라고 합니다.
function printSize(product) {
~~~~~~~ 타입 정의도 없고 추론할 수도 없음
console.log(product.size);
}
새로 시작하는 타입스크립트 프로젝트라면 무조건 켜는 걸 추천드리지만, 기존에 자바스크립트로 만든 프로젝트를 타입스크립트로 옮기는 중이라면 이 옵션을 잠시 끄는 것도 좋습니다. 아래처럼 설정하면 strict 규칙들을 한꺼번에 설정하지만 noImplicitAny는 설정하지 않을 수 있습니다.
"strict": true,
"noImplicitAny": false,
strictNullChecks: null이 될 가능성이 있다면, 이런 경우를 반드시 처리하도록 하는 옵션입니다. 이것도 되도록이면 켜 놓으시는 걸 추천합니다. 예를 들자면 아래와 같은 코드는 strict null check를 할 때는 오류가 납니다. num 변수가 null이 될 수도 있으니까요. 반면에 strictNullChecks가 꺼져있다면 타입 오류가 나지 않습니다. 대신에 실행하는 도중에 num 변수에 null 값이 들어간다면 런타임 오류가 나겠죠?
let num: number | null;
// ...
num -= 1;
~~~
되도록이면 strictNullChecks를 켜시고, 이런 경우에는 반드시 null check를 하는 걸 권장드립니다.
let num: number | null;
// ...
if (num !== null) {
num -= 1;
}
node_modules 폴더에 설치된 패키지들의 타입 검사를 하지 않는 옵션입니다. 패키지 개발 과정에서 대부분 타입 검사가 이뤄지기 때문에, 중복으로 하지 않아도 됩니다. 그래서 이 옵션을 사용하시길 추천드립니다.
타입스크립트 컴파일러가 처리할 타입스크립트 파일들의 최상위 폴더를 정하는 옵션입니다. 기본 값으로는 처리하는 파일들의 경로를 종합해서 최상위 폴더를 정합니다. 만약 tsconfig.json 파일과 같은 폴더에 있는 src 폴더를 최상위 폴더로 정하고 싶다면 아래와 같이 쓰면 됩니다.
{
"compilerOptions": {
"rootDir": "src",
}
}
outDir에 지정된 폴더 안에다가 rootDir의 디렉토리 구조에 따라서 자바스크립트 파일을 만듭니다. 값을 지정하지 않으면 소스코드 파일과 같은 폴더에 자바스크립트 파일을 만듭니다.
{
"compilerOptions": {
"outDir": "dist",
}
}
.json 파일을 임포트해서 사용하고 싶다면 이 옵션을 켜야 합니다.
import data from 'data.json';
// ...
tsc로 트랜스파일할 때 포함할 경로(include)와 포함하지 않을 경로(exclude)를 정해줄 수 있습니다. 배열로 경로 패턴을 적어주면 되는데요. */라는 코드는 아래의 모든 폴더, 모든 파일을 의미합니다. 참고로 이런 패턴을 Glob 패턴이라고 합니다. 혹시 궁금하신 분들은 위키피디아 Glob 문서를 참고해 보세요.
{
"compilerOptions": {
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
"module": "commonjs", /* Specify what module code is generated. */
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
"strict": true, /* Enable all strict type-checking options. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
}
"include": ["src/**/*", "tests/**/*"],
"exclude": ["bin/**/*"],
}
옵션이 너무 많기 때문에 모든 옵션들을 전부 알고 있을 필요는 없습니다. 그 밖의 다른 옵션들이 궁금하신 분들은 타입스크립트 공식 문서를 참고하시는 걸 추천드립니다.
참고로 VS Code에서는 옵션들을 자동완성 기능으로 작성할 수 있는데요. 무엇을 작성해야 할지 모를 때 Windows에서는 Ctrl + I, macOS에서는 Cmd + I를 입력하면 Suggestion이 뜹니다. 각 옵션에 대한 설명도 볼 수 있으니까 공부 목적이 아니라 프로젝트를 개발할 때는 이 기능을 활용하시는 걸 추천합니다.