
tsconfgi.json 파일 생성 커맨드
$ tsc --init
TL;DR 일반적으로 유용한 필드들
{
"compilerOptions": {
"target": "es5", // 'es3', 'es5', 'es2015', 'es2016', 'es2017','es2018', 'esnext' 가능
"module": "commonjs", //무슨 import 문법 쓸건지 'commonjs', 'amd', 'es2015', 'esnext'
"allowJs": true, // js 파일들 ts에서 import해서 쓸 수 있는지
"checkJs": true, // 일반 js 파일에서도 에러체크 여부
"jsx": "preserve", // tsx 파일을 jsx로 어떻게 컴파일할 것인지 'preserve', 'react-native', 'react'
"declaration": true, //컴파일시 .d.ts 파일도 자동으로 함께생성 (현재쓰는 모든 타입이 정의된 파일)
"outFile": "./", //모든 ts파일을 js파일 하나로 컴파일해줌 (module이 none, amd, system일 때만 가능)
"outDir": "./", //js파일 아웃풋(변환되서 저장되는 곳) 경로바꾸기[폴더 지정]
"rootDir": "./", //루트경로 바꾸기 (js 파일 아웃풋 경로에 영향줌)
"removeComments": true, //컴파일시 주석제거
"strict": true, //strict 관련, noimplicit 어쩌구 관련 모드 전부 켜기
"noImplicitAny": true, //any타입 금지 여부
"strictNullChecks": true, //null, undefined 타입에 이상한 짓 할시 에러내기
"strictFunctionTypes": true, //함수파라미터 타입체크 강하게
"strictPropertyInitialization": true, //class constructor 작성시 타입체크 강하게
"noImplicitThis": true, //this 키워드가 any 타입일 경우 에러내기
"alwaysStrict": true, //자바스크립트 "use strict" 모드 켜기
"noUnusedLocals": true, //쓰지않는 지역변수 있으면 에러내기
"noUnusedParameters": true, //쓰지않는 파라미터 있으면 에러내기
"noImplicitReturns": true, //함수에서 return 빼먹으면 에러내기
"noFallthroughCasesInSwitch": true, //switch문 이상하면 에러내기
"noEmit": true // noEmit을 true로 설정하면 최종결과물이 나오지 않게 된다. 이를 통해서 단순 타임 체크용으로 사용할 것인지 아니면 tsc를 컴파일용으로 사용할 것인지 지정할 수 있게 된다.
}
}
꼭 알아야 하는 필드들
target
'target'은 타입스크립트파일을 어떤 버전의 자바스크립트로 바꿔줄지 정하는 부분입니다. es5로 세팅해놓으면 es5 버전 자바스크립트로 컴파일(변환)해줍니다. 신버전을 원하면 es2016, esnext 이런 것도 입력할 수 있습니다.
만약 코드가 구식의 환경에서 배포된다면 더 낮은 버전을 지정해야 하고, 신식의 환경에서만 배포된다는 보장이 있으면 더 높은 타겟으로 정해도 됩니다.(자바스크립트 버전 지정 값을 넣지 않으면 default로 es5로 컴파일됩니다.)
다만, 타입스크립트 소스 코드에 Promise 코드가 있을 경우, 이는 ES5에서 지원해주지 않기 때문에 Typescript를 컴파일 하면 오류가 발생하니 이 부분은 유의해야 합니다.
또한 target 프로퍼티는 lib 프로퍼티의 기본값도 자동으로 결정시킵니다.
따라서 target 프로퍼티와 lib 프로퍼티를 권장되는 방식대로 직접 맞출 수도 있지만, 편의를 위해서 그냥 target 프로퍼티만 지정할 수도 있습니다.
target 프로퍼티 중에 ESNext 라는 값이 있는데, 가장 최신 기능의 자바스크립트 버전을 가리키는 값입니다.
현재 Typescript의 버전에 따라 ESNext가 가리키는 버전이 달라질 수 있기 때문에 주의해서 사용해야 합니다.
lib
Javascript 내장 라이브러리를 지정할 수 있습니다. Math API, document API 등이 그 예시입니다.
이 프로퍼티가 지정되어 있지 않다면, target 프로퍼티에서 지정한 버전에 따라 필요한 타입 정의들에 대한 정보가 자동으로 지정됩니다. 예를 들어, target 프로퍼티가 ES6 혹은 그 이상의 버전으로 지정되었는데, lib 프로퍼티가 지정되지 않는다면, 자동으로 lib 프로퍼티에는 ES2015(lib.es2015.d.ts 파일) 등의 라이브러리들이 지정되기 때문에 기본적으로 타입 정보를 전역으로 참조할 수 있게 됩니다.
lib 프로퍼티를 지정하지 않을 때 target 필드 지정에 따라 자동으로 설정되는 값은 다음과 같습니다.
- target이 es3이면 디폴트로 lib.d.ts를 사용
- target이 es5이면, 디폴트로 dom, es5, scripthost를 사용
- target이 es6이면, 디폴트로 dom, es6, dom.iterable, scripthost를 사용
"compilerOptions": {
"lib": ["es5", "es2015.promise", "dom"], // 컴파일 과정에 사용될 라이브러리 파일 설정
/*
es5: global type을 사용하기 위함 (Array, Boolean, Function 등..)
es2015.promise: Promise를 사용하기 위함
dom: setTimeout, console.log 등 dom에서 지원해주는 기능들을 사용하기 위함
*/
}
module / moduleResolution
module
module은 컴파일될 결과물이 어떤 module 방식으로 컴파일 될 지 정하는 프로퍼티입니다.
쉽게 이해하자면, module은 자바스크립트 파일간 import 문법을 구현할 때 어떤 문법을 쓸 지 정하는 곳입니다.
만일 import 구문을 es6로 컴파일 했을 때, 동일하게 import로 컴파일되어 commonJS환경의 node로 실행시 오류가 발생할 수도 있습니다. 따라서 import 구문을 require 구문으로 컴파일을 해줘야 할 때 module의 속성값을 commonJS로 지정하면 됩니다.
자바스크립트 모듈은 브라우저에서는 AMD(asynchronous module definition) 방식으로 동작하고, node.js 에서는 CommonJS 방식으로 동작합니다. 하지만 ESM의 등장이후로 브라우저에서 번들러와 함께 ESM 방식을 사용할 수 있게 되면서 특정 ES 버전을 명시하여 사용하는 추세입니다.
- CommonJS (target 프로퍼티가 ES3 혹은 ES5로 지정되었을 때의 기본값)
- ES6/ES2015 (target 프로퍼티가 ES6 혹은 그 이상의 버전으로 지정되었을 때의 기본값)
- 나머지 (ES2020, ESNext, AMD, UMD, System, None)
참고로 module 프로퍼티는 moduleResolution 프로퍼티의 기본값도 결정합니다.
module이 commonjs면 노드에서 작동하는 것을 의미하므로, moduleResoultion 키 값은 node이며, 만일 module이 amd(웹)면 classic으로 설정됩니다.
moduleResolution
moduleResolution은 module 옵션으로 버전에 따라 생성된 모듈을 어떤 식으로 분석할지 설정하는 것입니다.
올 수 있는 값으로 node16, nodenext, node10, bundler, classic이 있습니다.
node10은 이전에 node라고 불렸던 버전으로 단순히 cjs의 require만 지원해주며 현재는 이 node10을 사용할 일이 없다고 봐도 무방합니다. 또한 classic은 Typescript 1.6버전 출시 전까지 사용됐던 것으로 이제는 더 이상 사용되어서는 안 됩니다. 그렇기에 node10과 classic은 그냥 아예 사용 안 한다고 보셔도 무방합니다.
node16, nodenext는 ESM 방식과 CJS 방식의 가져오기 구문을 둘다 지원하여 서로다른 알고리즘을 해결할 수 있습니다. 또한 bundler라는 옵션이 있는데, 이는 Typescript 5 버전 이상부터 지원되는 옵션 값입니다. 외부 번들러와 함께 프로젝트가 빌드되고 있다면 쓸 수 있는 옵션입니다. 이는 Typescript에게 코드가 외부 tool에 의해서 번들될 것이니 가져오기 rule규칙을 완화[풀어주도록] 해달라고 알려주는 역할을 합니다. 그렇게 함으로써 확장자명을 붙이든 안붙이든 에러가 뜨지 않게 됩니다.
bundler를 옵션으로 설정하게 될 경우 module 필드에서는 package.json exports필드 및 다른 변화들을 구문분석(parsing) 할 수 있는 최소 es2015 또는 이후의 버전을 사용해야 합니다. 이해가 어렵다면, exports와 imports 필드에 대해서도 다뤄야하므로 여기서는 그냥 '최신기능 이용하려면 최신 기술을 사용해라'라는 뜻으로 이해하면 되겠습니다. node16과 nodenext와 같이 bundler 옵션은 package.json 파일의 imports와exports필드를 지원하지만, Node.js resolution modes와는 다르게 bundler는 imports 필드 내부 상대경로의 확장자명을 절대(never) 필요로 하지 않는다는 차이가 있습니다.

"compilerOptions": {
"module": "ESNext", /* 생성될 모듈 코드 설정: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
"moduleResolution": "Bundler", /* 모듈 분석 방법 설정 */
}
jsx
.tsx 확장자의 컴파일 결과 JSX 코드를 어떻게 컴파일할지 결정합니다.
- react : .js 파일로 컴파일 된다. (JSX 코드는 React.createElement() 함수의 호출로 변환됨)
- react-jsx : .js 파일로 컴파일 된다. (JSX 코드는 _jsx() 함수의 호출로 변환됨)
- react-jsxdev : .js 파일로 컴파일 된다. (JSX 코드는 _jsx() 함수의 호출로 변환됨)
- preserve : .jsx 파일로 컴파일 된다. (JSX 코드가 그대로 유지됨)
- react-native : .js 파일로 컴파일 된다. (JSX 코드가 그대로 유지됨)
"compilerOptions": {
// JSX를 사용할 때 react-jsx 코드를 컴파일하도록 설정합니다.
"jsx": "react-jsx",
}
noEmit
noEmit을 true로 설정하면 최종결과물이 나오지 않게 된다.
이를 통해서 단순 타임 체크용으로 사용할 것인지 아니면 tsc를 컴파일용으로 사용할 것인지 지정할 수 있게 된다.
declaration
declaration을 true로 설정하게 되면 해당 .ts 파일의 .d.ts 파일 또한 같이 출력물에 포함되게 된다. TS파일을 JS로 컴파일하는 과정에서 JS파일과 함께 d.ts 파일이 생성된다는 뜻입니다.
declaration 파일들만 따로 출력하게 하고 싶다면 declarationDir로 별도 지정해 줄 수 있다.
sourceMap
sourceMap을 true로 지정하면 출력물에 .js.map 이나 .jsx.map 파일을 포함된다.
inlineSourceMap을 true을 지정하면 .js 파일 내부에 source map이 포함된다.
두 속성은 같이 사용할 수 없다.
isolatedModules
isolatedModules을 true로 설정하면 프로젝트 내에 모든 각각의 소스코드 파일을 모듈로 만들기를 강제한다.
소스코드 파일에서 import 또는export를 사용하면 그 파일은 모듈이 된다.
만약 import / export를 하지 않으면 그 파일은 전역 공간으로 정의된다.
isolatedModules을 true로 돼 있다면 모듈로 소스코드를 작성하지 않을 경우 에러를 출력한다.
만약 babel과 같은 외부 도구를 사용한다면 isolatedModules를 true로 설정하는 것이 좋다.
babel은 typescript를 처리할 때 모든 파일을 module로 취급하기 때문에 다른 것은 몰라도isolatedModules 하나는 꼭 true로 설정해야 한다.
그래야 vscode에서 작성 시 import / export를 하지 않아서 문제가 생기는 실수를 방지할 수 있다.
esModuleInterop
ES6가 아닌 CommonJS의 경우 module의 export 방법이 다르다.
ES6의 경우 export를 할 때 이름을 지정하나 default로 내보내게 되는데 CommonJs의 경우 module.exports = xxx를 통해서 객체를 내보낼 수 있다.
이때 import가 호환이 안되게 된다.
// import moment from "moment";
import * as moment from "moment";
moment();
CommonJs로 작성된 moment는 import moment from "moment"로 import를 할 수 없어 위와 같이 작성해야만 한다.
이러한 문제의 불편함을 해소하기 위해서 esModuleInterop를 true를 설정한다.
typescript가 두 방식의 차이를 자동으로 해소할 것이다.
컴파일 경로 지정
🚨typesRoot와 types 설정은 주의해야 합니다.
자칫 잘못하면 다른 필요한 패키지들의 타입들을 자동 컴파일 과정에 포함하지 않을 수도 있습니다.(해결방법은 typesRoot에 제시)
전역 선언이 포함된 파일을 사용하는 경우에만 자동 포함이 중요하다는 점에 명심하세요 (모듈로 선언된 파일과 달리). 예를 들어 import "foo" 문을 사용한다면 TypeScript는 여전히 node_modules 및 node_modules/@types 폴더를 보고 foo 패키지를 찾을 것입니다.
typeRoot
- typeRoots는 배열로 설정하며 기본값은 ["node_modules/@types"]이다.
typescript가 정의돼 있는 type을 찾는 공간이 된다. - 지정하지 않아도 default로 "@types"라는 이름이 붙은 패키지들은 전부 컴파일 과정에 포함됩니다. 주의할 점은 typeRoot가 정의되면, 오직 typeRoots에 정의된 패키지들만 포함되게 된다는 점입니다. 예를 들어 다음과 같이 작성할 수 있겠습니다.
- 상위 호환으로 include와 files 필드가 있습니다.
{
"compilerOptions": {
"typeRoots": ["./typings", "./vendor/types"]
}
}
이 설정은 .d.ts 파일을 읽을 폴더로 ./typings와 ./vendor/types 폴더를 설정하여 밑의 모든 패키지들을 포함하되, 🚨./node_modules/@types 아래의 패키지들은 포함하지 않게 됩니다. (모든 경로는 tsconfig.json 파일을 기준으로 상대 경로입니다.)
만약 추가적인 type들을 정의한다면 별도의 type 디렉터리를 만들고 그 안에 .d.ts 파일을 만든 뒤 디렉터리를 typeRoots에 추가해 주면 된다.
예를 들어서 프로젝트의 루트 디렉터리에 @types/ 디렉터리를 만들었다면 ["node_modules/@types", "@types"]와 같이 설정해 주면 된다.
include에 이미 포함된 곳이라면 굳이 추가해줄 필요가 없다.
🚨 대부분이 잘못 알고 있는 것 중 하나가 프로젝트 내에서 type 파일을 만들게 되면 typeRoots에 추가해야 한다고 알고 있는데 include에 포함돼 있는 .d.ts 파일은 자동으로 typescript가 인식하므로 넣어줄 필요가 없다.
include 외에 있는 경우만 추가해주면 된다.
또한 🚨 추가적인 typeRoots를 설정했는데 "node_modules/@types"을 빼놓게 되면 기본으로 추가가 되지 않으니 문제가 될 수 있음으로 반드시 추가해야 한다.
{
"compilerOptions": {
"typeRoots": ["./typings", "./vendor/types", "./node_modules/@types]
}
}
typeRoots를 통해서 지정한 type 경로는 일반적으로 외부 라이브러리가 제공하는 모듈의 타입을 정의하기 위해서 사용한다. 만약 외부 모듈을 가져오려고 할 때 "Could not find a declaration file for module 'xxxx'."와 같은 에러 메세지가 나게 된다면 @types/xxxx 패키지를 설치하거나 직접 정의를 해줘야만 하는데 직접 정의하게 될 경우 이 경로에 작성하면 된다.
프로젝트 내의 타입을 정의하기 위해서 사용하지 않기를 바란다.
types
types 라는 옵션도 있습니다.
지정하지 않아도 default 모든 @types 패키지를 컴파일 과정에 포함하게 되는 것은 동일합니다. 🚨주의사항으로 이 types 설정에 포함되면 여기에 나열된 패키지들만 global scope에 포함되게 됩니다. 예를 들어 다음과 같은 코드가 있습니다.
{
"compilerOptions": {
"types": ["node", "jest", "express"]
}
}
이 tsconfig.json은 오직 ./node_modules/@types/node, ./node_modules/@types/jest및 ./node_modules/@types/express만 포함합니다. 🚨node_modules/@types/* 아래의 다른 패키지는 포함되지 않습니다.
types 패키지는 index.d.ts 파일이 있는 폴더 또는 폴더에 types 필드를 가진 package.json가 있는 폴더입니다.
"types": []를 지정하면 @types 패키지가 자동으로 포함되지 않습니다.
files (패턴 X)
예시
{
"compilerOptions": {
"module": "commonjs",
"noImplicitAny": true,
"removeComments": true,
"preserveConstEnums": true,
"sourceMap": true
},
"files": [
"core.ts",
"sys.ts",
"types.ts",
"scanner.ts",
"parser.ts",
"utilities.ts",
"binder.ts",
"checker.ts",
"emitter.ts",
"program.ts",
"commandLineParser.ts",
"tsc.ts",
"diagnosticInformationMap.generated.ts"
]
}
"files" 속성은 상대 또는 절대 파일 경로 목록을 갖습니다(패턴 사용 불가능)
밑에서도 얘기하지만 files는 exclude보다 강력합니다.( files > exclude > include )
include 와 exclude (패턴 O)
예시
{
"compilerOptions": {
"module": "system",
"noImplicitAny": true,
"removeComments": true,
"preserveConstEnums": true,
"outFile": "../../built/local/tsc.js",
"sourceMap": true
},
"include": [
"src/**/*"
],
"exclude": [
"node_modules",
"**/*.spec.ts"
]
}
files 필드의 존재 여부에 따라 기본값이 바뀐다.
files 필드가 존재하면, []로, 선언되어 있지 않다면 ["**/*"]으로 기본 값이 설정됩니다.
glob 패턴
include와 exclude 속성은 glob와 유사한 파일 패턴 목록을 갖습니다. 지원되는 glob 와일드 카드는 다음과 같습니다.
*0개 이상의 문자와 매칭 (디렉토리 구분 기호 제외)?한 문자와 매칭 (디렉토리 구분 기호 제외)**반복적으로 모든 하위 디렉토리와 매칭
glob 패턴의 구분에 * 또는 .*만 있다면, 지원하는 확장자 파일만 포함됩니다 (예: 기본적으로는 .ts, .tsx 및 .d.ts이고, allowJs true로 설정되어 있다면 .js와 .jsx).
"files"과 "include" 모두 지정되어 있지 않다면 컴파일러는 기본적으로 "exclude" 속성을 사용하여 제외된 것은 제외하고 모든 TypeScript (.ts,.d.ts 그리고 .tsx) 파일을 포함하는 디렉토리와 하위 디렉토리에 포함시킵니다. allowJs가 true로 설정되면 JS 파일(.js와 .jsx)도 포함됩니다. "files"과 "include" 모두 지정되어 있다면 컴파일러는 그 두 속성에 포함된 파일의 결합을 포함(합집합)합니다. "exclude" 속성이 지정되지 않으면, "outDir" 컴파일러 옵션을 사용하여 지정된 디렉토리의 파일은 제외됩니다.
files > exclude > include (강력한 순서)
"include"을 사용하여 포함된 파일들은 "exclude" 속성을 사용해 필터링할 수 있습니다.
그러나 "files" 속성을 명시적으로 사용하는 파일은 "exclude"에 관계없이 항상 포함됩니다.(🚀 files가 exclude 보다 강하다.)
"exclude" 속성에 디렉토리가 지정되지 있지 않다면 기본적으로 node_modules, bower_components, jspm_packages 그리고 <outDir>를 제외합니다.
"files" 또는 "include" 속성에 포함되어 있는 파일을[이] 참조하는 모든 파일도 포함됩니다.
예를 들어, 파일 B.ts가 또 다른 파일 A.ts에 의해 참조된다면, 참조 파일 A.ts가 "exclude" 목록에서도 지정되지 않는 한 B.ts는 제외될 수 없습니다.
컴파일러에는 출력이 가능한 파일이 포함되어 있지 않다는 점에 주의해야 합니다; 즉 입력에 index.ts가 포함되면 index.d.ts와 index.js는 제외됩니다. 그래서 일반적으로 확장자만 다른 파일은 서로 옆에 두지 않는 것이 좋습니다.
"compilerOptions" 속성은 생략될 수 있으며 생략하면 컴파일러의 기본 값이 사용됩니다. 지원되는 전체 목록은 컴파일러 옵션를 참고하세요. tsconfig.json 파일은 완전히 비어둘 수 있으며, 기본 컴파일러 옵션을 사용하여 기본적으로 (위에서 설명한대로) 포함된 모든 파일을 컴파일합니다. 커맨드 라인에 지정된 컴파일러 옵션은 tsconfig.json 파일에 지정된 옵션을 오버라이드합니다.
extends
tsconfig.json 파일은 extends 속성을 사용해 다른 파일의 설정을 상속할 수 있습니다.
모노레포 폴더구조에서 유용하게 사용됩니다.
extends는 tsconfig.json의 최상위 속성 (compilerOptions,files,include 및 exclude와 함께) 입니다.
extends' 값은 상속받을 다른 설정 파일의 경로를 포함하는 문자열입니다. 경로는 Node.js 해석 스타일을 사용할 수 있습니다.
예시
configs/base.json
{
"compilerOptions": {
"noImplicitAny": true,
"strictNullChecks": true
}
}
tsconfig.json:
{
"extends": "./configs/base",
"files": [
"main.ts",
"supplemental.ts"
]
}
tsconfig.nostrictnull.json:
{
"extends": "./tsconfig",
"compilerOptions": {
"strictNullChecks": false
}
}
레퍼런스
{ tsconfig.json } 제대로 알고 사용하기
tsconfig.json을 왜 그리고 무엇을 위해서 설정하는지 알아보고자 한다.
velog.io
https://typescript-kr.github.io/pages/tsconfig.json.html
TypeScript 한글 문서
TypeScript 한글 번역 문서입니다
typescript-kr.github.io
📘 타입스크립트 컴파일 설정 - tsconfig 옵션 총정리
타입스크립트 컴파일 설정 tsconfig.json은 타입스크립트를 자바스크립트로 변환 시키는 컴파일 설정을 한꺼번에 정의 해놓는 파일이라고 보면 된다. 프로젝트를 컴파일 하는데 필요한 루트 파일,
inpa.tistory.com