tsconfig 핵심 옵션 10가지
옵션 100개 중 매일 만나는 10개와 실전 조합.
tsconfig.json 은 처음 보면 옵션 100개에 압도됩니다. 다행히 실전에서 매일 만나는 건 10개 안팎. 10편은 그 10개의 의미·실전 값·언제 무엇을 선택할지 정리합니다. 기초 파트의 마지막 — 다음부터는 중급으로 들어갑니다.
2026년 표준 tsconfig — 한 번에
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "Bundler",
"lib": ["ES2022", "DOM"],
"strict": true,
"noUncheckedIndexedAccess": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"isolatedModules": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"outDir": "dist",
"rootDir": "src"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
이 한 묶음이 2026년 새 프로젝트의 기본값. 아래서 핵심 10개를 하나씩 풉니다.
1. target — 컴파일된 JS 의 문법 버전
"target": "ES2022" // 최신 Node·브라우저 대부분 OK
"target": "ES2015" // IE11 까지 — 거의 안 씀
"target": "ESNext" // 변환 안 함 (번들러가 다운레벨)
높을수록 변환 안 거치고 작은 코드. 2026년 새 프로젝트는 ES2022 또는 ESNext. async/await·optional chaining 같은 문법이 그대로 살아남습니다.
2. module — import/export 변환 방식
"module": "ESNext" // import/export 그대로 둠 (번들러용)
"module": "NodeNext" // Node 16+ 의 ESM/CJS 자동 판별
"module": "CommonJS" // require/module.exports 로 변환 (옛 Node)
3. moduleResolution — import 경로 찾는 규칙
"moduleResolution": "Bundler" // 2026 표준 (vite/esbuild 호환)
"moduleResolution": "NodeNext" // Node 의 정식 ESM 규칙
"moduleResolution": "Node" // 옛 방식 (확장자 생략 등)
2026 권장 조합. 새 프론트엔드·CLI 프로젝트는 module: "ESNext" + moduleResolution: "Bundler". 순수 Node 백엔드는 module: "NodeNext" + moduleResolution: "NodeNext". 둘이 짝꿍이라 섞으면 에러.
4. strict — 한 옵션이 7개를 한꺼번에
"strict": true
// = strictNullChecks
// + noImplicitAny
// + strictFunctionTypes
// + strictBindCallApply
// + strictPropertyInitialization
// + noImplicitThis
// + useUnknownInCatchVariables
// + alwaysStrict
새 프로젝트는 무조건 true. 기존 프로젝트에 점진 도입 중이면 7개를 따로 켜기. strict 안 켜면 TS 의 가치 절반은 죽습니다.
5. noUncheckedIndexedAccess — 배열/객체 인덱스에 undefined
"noUncheckedIndexedAccess": true
const arr = [1, 2, 3];
const x = arr[10]; // x: number | undefined ← !!
// 옵션 끄면 x: number (실제론 undefined 인데 거짓말)
// 검사 없으면 컴파일 에러
console.log(x.toFixed(2)); // ❌ 'x' is possibly 'undefined'
if (x !== undefined) {
console.log(x.toFixed(2)); // ✅
}
이 옵션 켜는 게 strict 의 다음 단계입니다. 약간 짜증나지만 진짜 버그 잡습니다. 18편(strict 깊이) 에서 더.
6. lib — 사용 가능한 표준 라이브러리
"lib": ["ES2022", "DOM"] // 브라우저 코드
"lib": ["ES2022"] // 순수 Node (DOM 없음)
"lib": ["ES2022", "WebWorker"] // Service Worker
document·fetch 같은 브라우저 API 가 안 보이면 DOM 빠져있어요. Node 만 쓰는 코드에서 실수로 window 못 쓰게 하려면 DOM 제외.
7. include · exclude · files
"include": ["src/**/*"], // glob 패턴
"exclude": ["node_modules", "dist", "**/*.test.ts"],
"files": ["src/index.ts"] // 명시적 (drop 거의 안 씀)
include 없으면 프로젝트 전체. node_modules 는 기본 exclude 라서 명시 안 해도 OK 지만 명시가 안전.
8. paths · baseUrl — 경로 alias
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
"@components/*": ["src/components/*"]
}
9편에서 한 줄 — 런타임에는 번들러가 알아야 동작. TSC 만으로는 동작 안 함.
9. esModuleInterop + allowSyntheticDefaultImports — CJS 호환
"esModuleInterop": true,
"allowSyntheticDefaultImports": true
// 켜기 전 — CJS 모듈 import 어색
import * as React from "react";
// 켠 후 — default 처럼 자연스럽게
import React from "react";
거의 모든 코드베이스가 켭니다. 안 켜면 CJS 라이브러리 import 가 어색해져요.
10. skipLibCheck — 빌드 속도
"skipLibCheck": true
node_modules 안의 .d.ts 파일 타입 체크를 생략. 빌드 시간 크게 줄고, 라이브러리 타입 에러로 빌드가 막히는 사고도 막아줍니다. 거의 항상 true.
실전 한 표 — 환경별 추천
| 환경 | module | moduleResolution | lib |
|---|---|---|---|
| React / Vite | ESNext | Bundler | ES2022, DOM |
| Next.js | ESNext | Bundler | ES2022, DOM |
| Node 백엔드 (ESM) | NodeNext | NodeNext | ES2022 |
| CLI / 도구 | NodeNext | NodeNext | ES2022 |
| 라이브러리 발행 | ES2022 | Bundler | ES2022 |
대부분의 경우 처음부터 만들지 마세요. npm create vite, npx create-next-app, npm init -y && npx tsc --init 같은 스타터가 합리적인 기본을 제공합니다. 그 다음 위 10개를 한 번씩 훑어보고 프로젝트 성격에 맞게 미세 조정.
11편 — 유틸리티 타입 (중급 시작)
Partial·Pick·Omit·Record — TS 가 제공하는 즉시 쓸 수 있는 타입 도구들.
이전: 9편 모듈 · 현재: 10편 (기초 마지막) · 다음 → 11편 유틸리티 타입 (중급 시작) · 진행: 10/20