Flag `strict` di `tsconfig.json` adalah singkatan yang mengaktifkan sekelompok pemeriksaan individual: `strictNullChecks`, `noImplicitAny`, `strictFunctionTypes`, `strictBindCallApply`, `strictPropertyInitialization`, dan `noImplicitThis`. Masing-masing menangani kategori bug runtime yang berbeda. Mengaktifkan satu flag `strict: true` setara dengan mengaktifkan semuanya sekaligus.
Daripada mengaktifkan semua flag strict sekaligus, artikel ini menyarankan pendekatan bertahap: aktifkan `strictNullChecks` terlebih dahulu karena memiliki rasio sinyal-ke-noise tertinggi untuk bug nyata, perbaiki error tersebut, lalu aktifkan `noImplicitAny`, kemudian sisanya. Anda bisa menggunakan `skipLibCheck: true` sementara dan `@ts-expect-error` secara jarang sebagai jalan keluar. Penulis berhasil mengurangi satu proyek warisan dari 847 error strict menjadi nol selama tiga minggu sambil tetap mengirimkan fitur secara paralel.
Sebelum `strictNullChecks`, TypeScript mengizinkan `null` dan `undefined` ditetapkan ke tipe apa pun — inilah akar penyebab error `Cannot read properties of null` yang menyumbang lebih banyak insiden produksi dari penyebab tunggal lainnya. Dengan flag ini diaktifkan, TypeScript memaksa penanganan `null` dan `undefined` secara eksplisit, sehingga operator seperti optional chaining (`?.`) dan nullish coalescing (`??`) menjadi bagian yang disengaja dalam basis kode.
Tipe statis TypeScript tidak ada saat runtime, sehingga tidak bisa memvalidasi data yang datang dari respons API eksternal. Artikel ini menyarankan penggunaan Zod untuk mengurai dan mengetik respons API di batas — ini memberikan keamanan tipe saat runtime sekaligus memenuhi persyaratan analisis statis strict mode. Untuk library pihak ketiga lama yang paket `@types`-nya mengembalikan `any`, menulis fungsi wrapper yang sempit dengan tipe eksplisit dapat mencapai efek yang sama.
Strict mode mengharuskan compiler TypeScript melakukan pemeriksaan tipe yang lebih menyeluruh, yang biasanya meningkatkan waktu build sebesar 5–15%. Artikel ini berpendapat bahwa pertukaran ini sepadan karena tipe strict juga meningkatkan akurasi IntelliSense di IDE, keandalan jump-to-definition, dan dukungan refactoring — peningkatan pengalaman pengembang yang membenarkan kenaikan waktu kompilasi yang moderat.
Aplikasi yang dibangun dengan TypeScript strict mode yang diaktifkan mengalami sekitar 40% lebih sedikit bug terkait tipe yang mencapai produksi. Saya telah mengaktifkan strict mode di setiap proyek yang saya sentuh selama dua tahun terakhir, termasuk selama migrasi proyek warisan. Rasa sakit awal — dinding error tipe saat Anda pertama kali membalik sakelar — nyata. Tapi apa yang strict mode ungkap lebih berharga dari fitur apa pun yang bisa Anda bangun selama jendela refaktor tersebut.
Flag strict di tsconfig.json adalah singkatan untuk sekelompok pemeriksaan individual: strictNullChecks, noImplicitAny, strictFunctionTypes, strictBindCallApply, strictPropertyInitialization, dan noImplicitThis. Masing-masing menangani kategori bug runtime yang berbeda.
Sebelum strictNullChecks, TypeScript membiarkan string | null | undefined semuanya diperlakukan sebagai string. Beginilah Anda mendapatkan Cannot read properties of null (reading 'name') di produksi — error yang menyumbang lebih banyak insiden produksi dari penyebab tunggal lainnya. Dengan strictNullChecks diaktifkan, TypeScript memaksa Anda menangani null dan undefined secara eksplisit. user?.name alih-alih user.name.
"strict": true ──► enables all of these:
│
├── strictNullChecks ← most important
│ Without: let x: string = null // OK (dangerous)
│ With: let x: string = null // Error: Type 'null' not assignable
│
├── noImplicitAny ← second most important
│ Without: function foo(x) { ... } // x is implicitly 'any'
│ With: function foo(x: string) // must be explicit
│
├── strictFunctionTypes ← function parameter safety
├── strictBindCallApply ← bind/call/apply type checking
├── strictPropertyInitialization ← class properties must init
└── noImplicitThis ← 'this' must be typed
Real bugs caught by strict mode in production Next.js apps:
──────────────────────────────────────────────────────────
// Prisma findUnique returns T | null
const user = await prisma.user.findUnique({ where: { id } })
user.name // 🔴 Error: Object is possibly 'null' — forces you to check
// Array.find returns T | undefined
const item = cart.items.find(i => i.id === id)
item.quantity // 🔴 Error: Object is possibly 'undefined'
// API response without explicit typing
const data = await fetch(url).then(r => r.json())
// With noImplicitAny + ts-reset: data is unknown, not any
// Forces you to validate before useDari mengaktifkan strict mode pada basis kode NestJS + Next.js ERP warisan dengan 15.000 baris: jangan aktifkan semua flag strict sekaligus. Aktifkan strictNullChecks terlebih dahulu (ia memiliki rasio sinyal-ke-noise tertinggi untuk bug nyata), perbaiki, lalu aktifkan noImplicitAny, lalu sisanya. Pendekatan bertahap ini memungkinkan Anda mengirimkan migrasi secara bertahap tanpa penulisan ulang besar-besaran.
Dalam aplikasi Next.js berbasis Prisma, tangkapan paling umum adalah: (1) findUnique() mengembalikan T | null — tanpa strictNullChecks, Anda akan mengakses hasilnya langsung dan crash saat catatan tidak ada. (2) Array.find() mengembalikan T | undefined. (3) Optional chaining pada respons API. (4) Inisialisasi properti kelas — strict mode menangkap layanan NestJS di mana dependensi tidak diinjeksikan dengan benar.
// tsconfig.json — enable strict
{
"compilerOptions": {
"strict": true,
"skipLibCheck": true, // skip during migration
"noUncheckedIndexedAccess": true, // bonus: arr[0] is T | undefined
"exactOptionalPropertyTypes": true // bonus: stricter optional props
}
}
// NestJS tsconfig — extra config needed for DI
{
"compilerOptions": {
"strict": true,
"strictPropertyInitialization": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true
}
}
// NestJS: handle strict property initialization with !
@Injectable()
export class UsersService {
@InjectRepository(User)
private readonly userRepo!: Repository<User> // ! = Definite Assignment Assertion
}
// Prisma + strict mode: always handle null
const user = await prisma.user.findUnique({ where: { id } })
if (!user) throw new NotFoundException(`User ${id} not found`)
// After the check, user is narrowed to User (not User | null)
console.log(user.name) // ✅ TypeScript knows this is safe
// ts-reset for better built-in types (optional but recommended)
// npm install --save-dev @total-typescript/ts-reset
// Create reset.d.ts:
import "@total-typescript/ts-reset"
// Now: fetch().json() returns unknown (not any)
// Array.includes() accepts broader types correctly
// JSON.parse() returns unknown (not any)Beberapa library lama memiliki paket @types yang tidak sepenuhnya kompatibel dengan strict mode — mereka akan mengembalikan any dari fungsi yang biasanya ditangkap strict mode. Solusinya: tulis fungsi wrapper yang sempit yang menambahkan tipe yang diharapkan strict mode. Untuk klien API, gunakan Zod untuk mengurai dan mengetik respons API di batas — ini memberi Anda keamanan tipe runtime DAN memenuhi analisis statis strict mode.
Mengaktifkan strict mode pada basis kode yang ada yang besar akan menghasilkan ratusan atau ribuan error — jangan biarkan ini menghalangi Anda. Gunakan pendekatan yang direkomendasikan tim TypeScript: aktifkan strict di tsconfig.json tapi tambahkan 'skipLibCheck: true' sementara, dan gunakan @ts-expect-error secara jarang untuk kasus yang akan Anda tangani nanti. Lacak jumlah error Anda sebagai metrik. Saya mengurangi satu proyek warisan dari 847 error strict menjadi 0 selama tiga minggu sambil mengirimkan fitur secara paralel.
Strict mode membuat compiler TypeScript bekerja lebih keras — pemeriksaan tipe lebih menyeluruh. Waktu build meningkat secara moderat (5-15% biasanya). Sebagai gantinya, Anda mendapatkan autocomplete IDE yang lebih baik (IntelliSense lebih akurat dengan tipe strict), jump-to-definition yang lebih baik, dan dukungan refactoring yang lebih baik. Peningkatan pengalaman pengembang dari IntelliSense yang lebih baik saja membenarkan peningkatan waktu kompilasi.
strict: true ada di tsconfig.json setiap proyek yang saya mulai. Tanpa pengecualian. Untuk proyek NestJS, saya mengaktifkannya secara eksplisit di tsconfig.json bersama strictPropertyInitialization: true (yang tidak diaktifkan NestJS secara default karena dependency injection membingungkan pemeriksa inisialisasi properti — gunakan Definite Assignment Assertion ! pada properti yang diinjeksikan).
TypeScript strict mode adalah baseline, bukan langit-langit. Lapisi di atasnya: ESLint dengan aturan @typescript-eslint/recommended (terutama no-explicit-any dan no-non-null-assertion), Zod untuk validasi runtime di batas API, dan ts-reset untuk koreksi tipe global. Stack ini memberi Anda keamanan tipe di compile-time + lint-time + runtime — tiga lapisan perlindungan terhadap ketidakcocokan bentuk.