Strict mode adalah opsi "strict": true di tsconfig.json. Opsi ini adalah satu sakelar untuk delapan flag pengecekan tipe yang menangkap any implisit, null dan undefined yang tidak dicek, assignment fungsi yang tidak aman, dan field class yang tidak diinisialisasi. Di TypeScript 7, strict aktif secara default. Beginilah bentuk kode yang lolos pengecekannya:
Output-nya no user, SyntaxError dan 42. Hapus : number, ?., atau pengecekan instanceof, dan file-nya tidak lagi lolos kompilasi.
Mengaktifkannya
{
"compilerOptions": {
"strict": true
}
}
Flag individual mengalahkan strict, ke arah mana pun. "strict": true, "strictNullChecks": false mempertahankan semuanya kecuali pengecekan null; "strict": false, "noImplicitAny": true hanya mengaktifkan flag itu saja. strict juga otomatis mengikutsertakanmu dalam pengecekan yang ditambahkan di rilis mendatang, karena flag baru dari keluarga strict ikut bergabung ke kelompok itu.
strict milik TypeScript tidak ada hubungannya dengan direktif "use strict" di JavaScript, yang merupakan mode runtime. TypeScript 7 selalu menghasilkan "use strict" di tempat yang membutuhkannya, dan menyetel alwaysStrict: false adalah error TS5108 (opsi itu sudah dihapus).
Apa yang Ditangkap Setiap Flag
| Flag | Yang dilaporkan | Error |
|---|---|---|
noImplicitAny | parameter atau variabel yang tipenya diam-diam akan menjadi any | TS7006 Parameter 'x' implicitly has an 'any' type. |
strictNullChecks | memakai nilai yang mungkin null atau undefined | TS18048 'u' is possibly 'undefined'. |
strictFunctionTypes | meng-assign fungsi yang tipe parameternya lebih sempit dari yang diperlukan | TS2322 |
strictBindCallApply | argumen yang salah untuk .call, .bind dan .apply | TS2345 |
strictPropertyInitialization | field class yang tidak pernah di-assign | TS2564 Property 'name' has no initializer and is not definitely assigned in the constructor. |
noImplicitThis | this dengan tipe any implisit, seperti di function yang bersarang | TS2683 |
useUnknownInCatchVariables | memakai variabel catch sebelum mempersempit tipenya (tipenya unknown) | TS18046 'err' is of type 'unknown'. |
strictBuiltinIteratorReturn | menganggap it.next().value dari iterator bawaan selalu terdefinisi | TS2322 |
Dua flag yang paling banyak mengubah kode adalah noImplicitAny dan strictNullChecks. Blok ini sengaja melanggar keduanya:
Blok ini mencetak index.ts(2,17): error TS7006: Parameter 'x' implicitly has an 'any' type. dan index.ts(11,13): error TS18048: 'user' is possibly 'undefined'. Tanpa strict, kode ini lolos kompilasi lalu crash saat runtime dengan TypeError: Cannot read properties of undefined (reading 'name'). Dengan strict, crash itu berubah menjadi error kompilasi. Perbaikannya ada di blok pertama halaman ini.
strictFunctionTypes: Kenapa Ada
Fungsi yang hanya menangani string tidak boleh dipakai di tempat yang bisa menerima number. Pengecekan di bawah ini diredam dengan @ts-expect-error supaya kamu bisa menjalankannya dan melihat apa yang dicegah oleh error itu:
Tanpa komentar itu, assignment-nya adalah error TS2322, Type '(s: string) => void' is not assignable to type 'Handler'., diikuti Types of parameters 's' and 'value' are incompatible. Ada satu pengecualian yang sengaja dipertahankan: parameter method yang dideklarasikan dengan sintaks method (handle(value: string | number): void di dalam interface) masih dicek dengan cara yang lebih longgar, jadi shout bisa di-assign ke method seperti itu tanpa error.
strictPropertyInitialization
Setiap field class harus mendapat nilai di deklarasinya atau di constructor. Ada tiga cara untuk memenuhinya:
Output:
Account {
owner: 'Ada',
balance: 0,
history: [],
lastLogin: undefined,
sessionId: 's-1'
}
Property lastLogin dan sessionId ada dengan nilai undefined karena field class adalah field JavaScript yang nyata pada target ES2022. ! menghapus pengecekannya tanpa menambah perlindungan apa pun saat runtime, jadi utamakan bentuk lainnya. Flag ini butuh strictNullChecks; mematikan flag itu ikut menonaktifkannya.
Mengaktifkan Strict di Proyek yang Sudah Ada
Mengalihkan codebase besar ke strict sekaligus bisa menghasilkan ratusan error. Karena strict adalah default di TypeScript 7, meng-upgrade proyek yang tsconfig.json-nya tidak pernah menyebut strict akan mengaktifkannya dengan sendirinya; tulis "strict": false kalau kamu butuh perilaku lama selama migrasi. Jalur yang menjaga build tetap hijau:
- Tambahkan
"strict": truedan matikan flag yang paling banyak error-nya, biasanya"strictNullChecks": falsedan"noImplicitAny": false. - Perbaiki error yang tersisa, lalu aktifkan satu flag lagi dan ulangi.
- Untuk
noImplicitAny, sebagian besar perbaikannya adalah anotasi parameter. UntukstrictNullChecks, tambahkan| undefineddi tempat nilai bisa hilang, lalu tangani dengan?.,??atau pengecekanif. - Kalau sebuah perbaikan harus ditunda, taruh
// @ts-expect-errorbeserta alasannya di baris itu. Tidak seperti@ts-ignore, komentar ini melaporkan error begitu masalahnya hilang, jadi daftarnya menyusut dengan sendirinya.
Jangan memakai as any atau ! untuk meredam error secara massal: masing-masing menyembunyikan tepat bug yang ingin ditemukan oleh flag itu.
Flag Berguna yang Tidak Termasuk dalam Strict
Flag ini terpisah karena menolak kode yang sering kali sebenarnya benar. Banyak proyek tetap mengaktifkannya.
| Flag | Fungsinya |
|---|---|
noUncheckedIndexedAccess | arr[i] dan record[key] memuat undefined di tipenya |
exactOptionalPropertyTypes | debug?: boolean menerima key yang tidak ada, tetapi tidak menerima debug: undefined |
noImplicitReturns | setiap jalur kode di fungsi yang punya nilai kembalian harus melakukan return (TS7030) |
noImplicitOverride | method yang meng-override method dasar harus menyebut override (TS4114) |
noFallthroughCasesInSwitch | case yang tidak kosong harus diakhiri break, return atau throw (TS7029) |
noUnusedLocals, noUnusedParameters | variabel dan parameter yang tidak dipakai menjadi error |
noPropertyAccessFromIndexSignature | key dari index signature harus memakai obj["key"], bukan obj.key |
noUncheckedIndexedAccess menangkap paling banyak bug nyata. Kalau flag ini aktif:
const scores = [90, 85];
const d: Record<string, number> = {};
const third: number = scores[2]; // error TS2322: Type 'number | undefined' is not assignable to type 'number'.
const c: number = d["x"]; // same error
const safe = scores[2] ?? 0; // number
for (const s of scores) { // for...of is not affected: s is number
console.log(s);
}
tsc --init di TypeScript 7 mengaktifkan noUncheckedIndexedAccess dan exactOptionalPropertyTypes di konfigurasi yang dihasilkannya, di samping strict.
Pertanyaan yang sering diajukan
Apa fungsi strict mode di TypeScript?
"strict": true mengaktifkan sekelompok pengecekan yang lebih ketat: noImplicitAny, strictNullChecks, strictFunctionTypes, strictBindCallApply, strictPropertyInitialization, noImplicitThis, useUnknownInCatchVariables dan strictBuiltinIteratorReturn. Bersama-sama, flag ini mencegah any muncul diam-diam dan menjadikan null serta undefined bagian dari sistem tipe.
Apakah strict mode aktif secara default di TypeScript?
Di TypeScript 7, ya: strict default-nya true, jadi proyek tanpa pengaturan strict mendapat semua pengecekan strict. tsc --init juga menulis "strict": true secara eksplisit. Untuk menonaktifkannya, kamu harus menulis "strict": false.
Bisakah saya mematikan satu pengecekan strict tetapi tetap memakai yang lain?
Bisa. Flag individual menimpa strict: { "strict": true, "strictNullChecks": false } mempertahankan semua pengecekan strict kecuali pengecekan null. Inilah cara yang biasa untuk memigrasi codebase besar satu flag demi satu flag.
Apakah strict mode TypeScript sama dengan "use strict" di JavaScript?
Tidak. "use strict" adalah mode runtime JavaScript yang mengubah perilaku kode. strict milik TypeScript hanya mengubah apa yang dilaporkan type checker. TypeScript 7 selalu menghasilkan "use strict" untuk output yang bukan module, dan alwaysStrict: false sekarang adalah opsi yang sudah dihapus.
Apakah strict mencakup noUncheckedIndexedAccess?
Tidak. noUncheckedIndexedAccess, exactOptionalPropertyTypes, noImplicitReturns, noImplicitOverride dan noFallthroughCasesInSwitch adalah flag terpisah yang kamu aktifkan sendiri. tsc --init mengaktifkan dua yang pertama di konfigurasi yang dihasilkannya.