tsconfig.json adalah file konfigurasi sebuah proyek TypeScript. Saat kamu menjalankan tsc tanpa argumen, compiler mencarinya di folder saat ini (lalu di folder induknya), membaca opsi di compilerOptions, dan mengecek file yang didaftarkan oleh include. Contoh yang kecil tetapi lengkap:
{
"compilerOptions": {
"target": "es2022",
"module": "nodenext",
"strict": true,
"rootDir": "./src",
"outDir": "./dist"
},
"include": ["src"]
}
Konfigurasi ini meng-compile setiap file TypeScript di src menjadi JavaScript di dist, sebagai kode ES2022, memakai aturan module Node.js, dengan semua pengecekan strict aktif. npx tsc --init membuat file awal yang lebih panjang dengan komentar di setiap opsi.
File ini adalah JSON dengan komentar: komentar //, komentar /* */, dan koma di akhir semuanya diterima.
Konfigurasi Awal yang Direkomendasikan
Untuk aplikasi atau script Node.js:
{
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist",
"target": "es2024",
"lib": ["es2024"],
"module": "nodenext",
"types": ["node"],
"strict": true,
"noUncheckedIndexedAccess": true,
"verbatimModuleSyntax": true,
"skipLibCheck": true,
"sourceMap": true
},
"include": ["src"]
}
Konfigurasi ini butuh npm install --save-dev @types/node untuk tipe Node.js. Dengan module: "nodenext", field "type" di package.json menentukan apakah file .ts adalah ES module ("type": "module") atau CommonJS ("type": "commonjs", yang ditulis oleh npm init -y). Pakai "type": "module" untuk proyek baru yang memakai import dan export.
Untuk kode yang di-build oleh bundler seperti Vite, esbuild atau webpack, bundler-nya yang menulis JavaScript dan tsc hanya mengecek:
{
"compilerOptions": {
"target": "es2022",
"lib": ["es2022", "dom"],
"module": "preserve",
"noEmit": true,
"strict": true,
"noUncheckedIndexedAccess": true,
"verbatimModuleSyntax": true,
"isolatedModules": true,
"skipLibCheck": true,
"jsx": "react-jsx"
},
"include": ["src"]
}
Starter framework (Vite, Next.js, Angular) membuat tsconfig.json sendiri. Mulailah dari milik mereka alih-alih menggantinya.
Opsi yang Penting
| Opsi | Fungsinya | Default TypeScript 7 |
|---|---|---|
target | Versi JavaScript output; sintaks yang lebih baru ditulis ulang untuk target yang lebih lama | es2025 |
lib | Tipe API bawaan yang dikenal type checker (Array.prototype.at, Map, document) | Sesuai target, ditambah DOM |
module | Jenis kode module yang dihasilkan dan aturan module yang diterapkan | esnext |
moduleResolution | Cara path import ditemukan di disk | nodenext atau node16 dengan module yang sesuai, selain itu bundler |
strict | Mengaktifkan seluruh keluarga pengecekan strict | true |
rootDir | Folder yang strukturnya dicerminkan ke outDir | Folder tempat tsconfig.json berada |
outDir | Tempat file .js (dan .d.ts) ditulis | Di sebelah setiap file sumber |
include / exclude / files | File mana yang menjadi bagian proyek | Setiap file .ts di bawah folder itu |
types | Paket @types mana yang dimuat tanpa import | [], tidak ada |
noEmit | Hanya mengecek, tidak menulis apa pun | false |
declaration | Juga menulis file deklarasi tipe .d.ts | false |
sourceMap | Menulis file .js.map untuk debugger | false |
esModuleInterop | Membuat import x from "cjs-package" berfungsi dengan paket CommonJS | true (tidak bisa dimatikan) |
skipLibCheck | Melewati pengecekan tipe file .d.ts, termasuk yang ada di node_modules | false |
target dan lib
target menentukan versi JavaScript tempat output harus berjalan. Sintaks yang lebih baru dari target akan ditulis ulang: dengan "target": "es2017", field class atau ??= diubah menjadi kode yang lebih lama. Target terendah yang diterima TypeScript 7 adalah es2015 (es6); es5 sudah dihapus.
target tidak menambahkan API runtime yang tidak ada. Mendeskripsikannya adalah tugas lib, dan menyediakannya adalah tugas polyfill. lib memberi tahu type checker object dan method bawaan mana yang ada. Default-nya mengikuti target dan juga memuat tipe DOM browser, jadi document tetap lolos pengecekan tipe bahkan di proyek Node.js, kecuali kamu mengatur lib sendiri. Memakai method dari standar yang lebih baru daripada lib-mu adalah error kompilasi:
src/b.ts(1,24): error TS2550: Property 'toSorted' does not exist on type 'number[]'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2023' or later.
Contoh yang bisa dijalankan di dokumentasi ini memakai lib es2022, jadi toSorted, Object.groupBy dan method Set yang baru tidak tersedia di dalamnya.
module dan moduleResolution
module punya tiga nilai yang masuk akal untuk kode baru:
nodenext: untuk kode yang dijalankan Node.js. Setiap file adalah ESM atau CommonJS sesuai ekstensinya (.mts,.cts) atau"type"dipackage.jsonterdekat, persis seperti cara Node menentukannya. Import relatif di ES module butuh ekstensi file, ditulis sebagai.jswalaupun sumbernya.ts:import { add } from "./math.js".moduleResolutionmengikuti secara otomatis.preserve: untuk kode yang diproses bundler. Import dibiarkan seperti yang ditulis, dan resolution memakai aturanbundler, yang mengizinkan import tanpa ekstensi.esnext: output ES module biasa, dengan resolutionbundler. Ini default kalaumoduletidak diatur.
Error pertama yang umum dengan konfigurasi tsc --init berasal dari npm init -y yang menulis "type": "commonjs":
src/main.ts(1,10): error TS1295: ECMAScript imports and exports cannot be written in a CommonJS file under 'verbatimModuleSyntax'.
File itu memakai import, tetapi package.json menyatakan proyeknya CommonJS. Ubah "type" menjadi "module". Halaman module membahas import dan export secara detail.
strict dan Opsi Pengecekan
"strict": true mengaktifkan sekelompok pengecekan sekaligus: noImplicitAny, strictNullChecks, strictFunctionTypes, strictBindCallApply, strictPropertyInitialization, strictBuiltinIteratorReturn, noImplicitThis dan useUnknownInCatchVariables. Ini default di TypeScript 7 dan aktif di setiap contoh yang bisa dijalankan di sini. Kode yang ditulis untuk strict mode mempersempit tipe sebelum memakai nilai yang mungkin tidak ada:
Tanpa anotasi, tipe sebuah parameter tidak bisa disimpulkan, dan noImplicitAny melaporkannya:
index.ts(2,17): error TS7006: Parameter 'n' implicitly has an 'any' type.
strict tidak mencakup setiap pengecekan yang berguna. Dua yang layak ditambahkan adalah noUncheckedIndexedAccess (elemen array atau pembacaan index signature bertipe T | undefined) dan exactOptionalPropertyTypes (property opsional tidak boleh di-set secara eksplisit ke undefined); tsc --init mengaktifkan keduanya. Pengecekan gaya seperti noUnusedLocals, noImplicitReturns dan noFallthroughCasesInSwitch nonaktif secara default.
File Mana: include, exclude, rootDir, outDir
Tanpa include atau files, proyek berisi setiap file .ts, .tsx dan .d.ts di folder itu dan subfolder-nya. node_modules selalu dikecualikan. outDir juga dikecualikan, tetapi hanya selama kamu belum mengatur exclude: daftar exclude buatanmu menggantikan default itu, jadi tambahkan folder output ke dalamnya. include dan exclude menerima pola glob:
{
"include": ["src", "scripts/**/*.ts"],
"exclude": ["src/**/*.test.ts"]
}
exclude hanya menyaring apa yang ditemukan include. File yang di-import oleh file lain yang termasuk tetap di-compile.
outDir adalah tempat output ditulis, dan rootDir adalah bagian pohon sumber yang dicerminkan ke sana: dengan "rootDir": "./src", src/api/users.ts menjadi dist/api/users.js. Atur keduanya. rootDir default-nya adalah folder tempat tsconfig.json berada, jadi kalau kamu hanya mengatur outDir sementara sumbernya ada di src, TypeScript 7 berhenti dengan:
error TS5011: The common source directory of 'tsconfig.json' is './src'. The 'rootDir' setting must be explicitly set to this or another path to adjust your output's file layout.
Opsi Output: noEmit, declaration, sourceMap
"noEmit": truemenjadikantscmurni type checker. Pakai saat alat lain (bundler,tsx, type stripping Node.js) yang menghasilkan JavaScript."declaration": truemenulis file.d.tsuntuk setiap module, yaitu tipenya tanpa kode. Library membutuhkannya supaya penggunanya mendapat tipe.declarationMapmenambahkan map untuk "go to definition" ke sumber.ts."sourceMap": truemenulis file.js.mapsupaya debugger dan stack trace menunjuk ke baris.ts."noEmitOnError": truetidak menulis apa pun selama masih ada error tipe. Tanpanya,tscmelaporkan error-nya dan tetap menulis JavaScript.
types, esModuleInterop dan skipLibCheck
types mendaftar paket @types yang dimuat secara global, tanpa import. Default TypeScript 7 adalah daftar kosong, jadi setelah npm install --save-dev @types/node kamu juga menambahkan "types": ["node"]; kalau tidak, process dan require tetap tidak dikenal (error TS2591: Cannot find name 'process'). Test runner dengan fungsi global, seperti describe milik Jest, masuk ke daftar yang sama.
esModuleInterop membuat default import dari paket CommonJS berfungsi (import express from "express"). Opsi ini selalu aktif di TypeScript 7, dan menyetelnya ke false adalah error.
skipLibCheck melewati pengecekan tipe file deklarasi. Opsi ini mempercepat build dan menghindari error di dalam node_modules yang tidak bisa kamu perbaiki, dengan risiko tidak menyadari konflik antara tipe dua library. Kebanyakan proyek mengaktifkannya.
Berbagi Pengaturan dengan extends
extends memuat konfigurasi lain dan membiarkan file ini menimpa sebagiannya:
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist"
},
"include": ["src"]
}
compilerOptions digabungkan per opsi, sedangkan include, exclude dan files dari konfigurasi dasar diganti, bukan digabungkan, kalau file ini mengaturnya. Path di file dasar di-resolve relatif terhadap file dasar itu. extends juga menerima paket: proyek @tsconfig/bases menerbitkan satu paket untuk setiap lingkungan, misalnya npm install --save-dev @tsconfig/node24 lalu "extends": "@tsconfig/node24/tsconfig.json".
Untuk melihat pengaturan akhir setelah semua extends dan default diterapkan, jalankan:
npx tsc --showConfig
Opsi yang Dihapus di TypeScript 7
TypeScript 6 menandai pengaturan ini sebagai deprecated dan TypeScript 7 menghapusnya. Konfigurasi yang masih memakai salah satunya gagal dengan error TS5108 atau TS5102, misalnya Option 'baseUrl' has been removed. Please remove it from your configuration.
| Pengaturan yang dihapus | Gunakan sebagai gantinya |
|---|---|
"target": "es5" | es2015 atau yang lebih baru |
"moduleResolution": "node" (node10) atau "classic" | nodenext atau bundler |
"module": "amd", "umd", "system", "none" | nodenext, esnext atau preserve, dan bundler untuk format lain |
baseUrl | Entri paths yang relatif terhadap file tsconfig |
outFile | Bundler |
downlevelIteration | Tidak ada: target mulai es2015 ke atas sudah mendukung iterasi secara native |
"esModuleInterop": false, "allowSyntheticDefaultImports": false, "alwaysStrict": false | Hapus barisnya; opsi-opsi ini selalu aktif |
Halaman TypeScript 7 mendaftar perubahan lain di rilis itu, termasuk default baru yang tidak dicakup tabel ini.
Pertanyaan yang sering diajukan
Apa itu tsconfig.json?
tsconfig.json adalah file konfigurasi sebuah proyek TypeScript. Keberadaannya menandai folder itu sebagai root proyek, compilerOptions mengatur cara compiler mengecek dan menghasilkan kode, dan include, exclude atau files menentukan file mana yang termasuk dalam proyek. Menjalankan tsc tanpa argumen akan membacanya.
Bagaimana cara membuat file tsconfig.json?
Jalankan npx tsc --init di folder proyek (dengan TypeScript sudah terpasang). Perintah itu menulis tsconfig.json dengan pengaturan yang direkomendasikan dan komentar di setiap opsi. Kamu juga bisa menulis file-nya secara manual; {} adalah tsconfig yang valid dan memakai semua nilai default.
Apa nilai target yang sebaiknya dipakai di tsconfig?
Versi JavaScript tertua yang harus bisa menjalankan kodemu. Untuk Node.js versi terbaru, es2022 atau yang lebih baru aman dipakai; default TypeScript 7 adalah es2025. target mengatur sintaks baru mana yang ditulis ulang untuk engine lama, sekaligus memilih lib default, yaitu kumpulan API bawaan yang dikenal oleh type checker.
Apa perbedaan module dan moduleResolution?
module menentukan jenis kode module yang ditulis compiler (import/export ES atau require CommonJS) dan aturan module mana yang berlaku. moduleResolution menentukan bagaimana path import seperti "./utils.js" atau "lodash" ditemukan di disk. Pakai nodenext untuk kode yang dijalankan Node.js, dan module: "preserve" (yang berarti resolution bundler) untuk kode yang diproses bundler.
Apakah tsconfig.json boleh berisi komentar?
Boleh. Compiler membacanya sebagai JSON dengan komentar: komentar // dan /* */ serta koma di akhir diperbolehkan, itulah sebabnya tsc --init menulis file yang penuh dengan opsi yang dikomentari. Alat lain yang mem-parse-nya sebagai JSON ketat bisa gagal karenanya.