tsconfig.json adalah file pengaturan TypeScript untuk satu proyek. Waktu kamu menjalankan tsc (TypeScript Compiler, program yang memeriksa dan mengubah .ts jadi .js), dia membaca file ini dulu. Kalau TypeScript itu satpam, tsconfig.json adalah surat tugasnya: ruangan mana yang dijaga (include), seketat apa dia memeriksa (strict), dan hasil kerjanya ditaruh di mana dan dalam bentuk apa (outDir, target, module).
🧪 Tebakan cepat: kamu pakai TypeScript versi terbaru, dan
tsconfig.json-mu cuma berisi{}. Apakahfunction sapa(nama) { ... }, parameter tanpa tipe, dapat error? Tebak dulu, jawabannya ada di bagian "strict: satu saklar, banyak pemeriksaan".
Bikin tsconfig.json
Di folder proyek, jalankan npx tsc --init. Hasilnya file tsconfig.json berisi pilihan yang disarankan, lengkap dengan komentar. Untuk materi ini kita pakai versi kecil:
{
"compilerOptions": {
"target": "es2022",
"module": "esnext",
"strict": true,
"rootDir": "./src",
"outDir": "./dist"
},
"include": ["src"]
}
compilerOptionsadalah pengaturan cara memeriksa dan cara menulis JavaScript-nya.target: versi JavaScript yang dihasilkan, misalnyaes2017ataues2022.module: bentukimport/exportdi JavaScript hasilnya.esnextuntuk proyek Vite atau browser modern,nodenextuntuk Node.js.strict: nyalakan semua pemeriksaan ketat sekaligus.rootDirdanoutDir: dari folder mana file.tsdiambil, dan ke folder mana file.jsditulis.src/index.tsjadidist/index.js.include: file mana yang diperiksa.
Lalu jalankan:
npx tsc: periksa semua file diinclude, lalu tulis.js-nya keoutDir.npx tsc --noEmit: cuma periksa, gak menulis file apa pun. Proyek Vite memeriksa dengan cara ini, karena Vite sendiri yang mengubah.tsjadi JavaScript.npx tsc --watch: periksa ulang tiap kali file disimpan.
include: file mana yang diperiksa
"include": ["src"] artinya semua file TypeScript di folder src dan subfolder-nya. File di luar itu gak dibaca sama sekali. Misalnya ada lain/x.ts berisi const x: number = "teks": error-nya gak muncul, karena file itu gak pernah diperiksa. exclude mengeluarkan sebagian dari include, misalnya "exclude": ["src/**/*.test.ts"]. Kalau exclude gak ditulis, node_modules dan folder outDir sudah dikeluarkan otomatis.
strict: satu saklar, banyak pemeriksaan
Ini src/index.ts yang dipakai di Lab:
export function sapa(nama) {
return "Halo, " + nama
}
const kota = ["Bandung", "Medan"]
const cari = kota.find((k) => k.startsWith("S"))
console.log(cari.toUpperCase())
const pertama = kota[0]
console.log(pertama.toUpperCase())
console.log(sapa(cari ?? "Tamu"))
"strict": true menyalakan beberapa pemeriksaan sekaligus, dua yang paling sering terasa:
noImplicitAny: parameter tanpa tipe ditolak.Parameter 'nama' implicitly has an 'any' type.ts(7006).strictNullChecks: nilai yang bisaundefinedataunullharus dicek dulu.findmengembalikanundefinedkalau gak ada yang cocok, jadicari.toUpperCase()ditolak:'cari' is possibly 'undefined'.ts(18048).
Sejak TypeScript 6.0, strict sudah nyala kalau gak ditulis apa-apa. Jadi tebakannya: iya, sapa(nama) tetap kena ts(7006) walau tsconfig-nya {}. Itu jawaban tebakannya. Tetap tulis "strict": true biar jelas buat yang membaca. Satu pemeriksaan bisa dimatikan sendiri, misalnya "noImplicitAny": false.
Ada satu pemeriksaan yang gak ikut strict: noUncheckedIndexedAccess. Kalau nyala, kota[0] dianggap bisa undefined (array-nya bisa saja kosong), jadi pertama.toUpperCase() juga ditolak. Dia cuma berpengaruh kalau strictNullChecks nyala.
| Pengaturan | ts(7006) di nama |
ts(18048) di cari |
ts(18048) di pertama |
Total |
|---|---|---|---|---|
"strict": false |
- | - | - | 0 |
"strict": true |
ada | ada | - | 2 |
"strict": true, "noImplicitAny": false |
- | ada | - | 1 |
"strict": true, "noUncheckedIndexedAccess": true |
ada | ada | ada | 3 |
Kenapa repot? Gak ada kota berawalan S, jadi cari memang undefined, dan kode ini crash waktu jalan: TypeError: Cannot read properties of undefined (reading 'toUpperCase'). Dengan strict mati, tsc diam dan bug-nya baru ketemu di browser.
target dan module: bentuk JavaScript hasilnya
Pengaturan pemeriksaan gak mengubah JavaScript yang ditulis. Yang mengubahnya target dan module. Baris terakhir pakai ??, yang baru ada di ES2020:
target |
Baris terakhir di dist/index.js |
|---|---|
es2017 |
console.log(sapa(cari !== null && cari !== void 0 ? cari : "Tamu")); |
es2020 ke atas |
console.log(sapa(cari ?? "Tamu")); |
target lama berarti JavaScript-nya ditulis ulang supaya browser lama paham. Lalu module mengatur export-nya. Dengan "module": "esnext", export function sapa tetap apa adanya. Dengan "module": "commonjs" (gaya Node.js lama), jadinya:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.sapa = sapa;
function sapa(nama) {
return "Halo, " + nama;
}
⚠️ Jebakan yang sering ketemu
- Menyalin tsconfig lama dari tutorial.
"target": "es5"dan"moduleResolution": "node"sudah dibuang. TypeScript 7 menolaknya:Option 'target=ES5' has been removed. Please remove it from your configuration.ts(5108). Pakaies2017ke atas. outDirtanparootDir. Di TypeScript 7, kalau file-mu ada disrcdan kamu menulisoutDir,rootDirharus ditulis juga: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.ts(5011).- Mengira
noUncheckedIndexedAccessikutstrict. Gak ikut. Tulis sendiri kalau mau. - Mematikan
strictkarena error-nya banyak. Tiap error di sana menunjuk bug yang bisa terjadi beneran, seperticariyangundefinedtadi.
TL;DR: tsconfig.json mengatur tsc untuk satu proyek, dibuat dengan npx tsc --init. include menentukan file yang diperiksa (exclude mengeluarkan sebagian), strict menyalakan pemeriksaan ketat seperti noImplicitAny dan strictNullChecks dan sudah nyala sejak TypeScript 6.0, noUncheckedIndexedAccess gak ikut strict. target menentukan versi JavaScript hasilnya, module bentuk import/export-nya, outDir dan rootDir folder hasil dan sumbernya. npx tsc memeriksa dan menulis .js, npx tsc --noEmit cuma memeriksa.