08 / 09
tsconfig ve strict mod
Derleyici ayarları, strict bayrakları ve CI'da tip kontrolü.
tsconfig.json Nedir
Bir klasörde tsconfig.json bulunması, o klasörün bir TypeScript projesinin kökü olduğunu gösterir. Dosya hangi dosyaların kontrol edileceğini ve hangi kuralların uygulanacağını tanımlar. tsc'yi dosya adı vermeden çalıştırdığınızda derleyici bu dosyayı bulunduğunuz klasörden başlayıp yukarı doğru arar.1
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"strict": true,
"noEmit": true
},
"include": ["src"]
}| Alan | Ne işe yarar |
|---|---|
compilerOptions | Derleyici ayarları; bu dersin büyük kısmı bunlarla ilgili |
include | Projeye dahil edilecek dosya ya da klasörler (tsconfig'e göre göreli)2 |
extends | Ayarları başka bir tsconfig dosyasından devralır2 |
references | Projeyi birbirine bağlı küçük parçalara böler (Vite şablonu bunu kullanır) |
strict Modu
TypeScript'in sıkılığı tek bir anahtardan çok bir ayar düğmesi gibidir: kontrolleri tek tek açıp kapatabilirsiniz. "strict": true hepsini birden açar.3
| Bayrak | Ne yapar |
|---|---|
noImplicitAny | Tipi çıkarılamayan değişken ve parametrelerin sessizce any olmasını engeller |
strictNullChecks | null ve undefined'ı ayrı tip yapar; kontrol etmeden kullanamazsınız |
strictFunctionTypes | Fonksiyon parametrelerini daha sıkı karşılaştırır |
strictBindCallApply | bind, call ve apply argümanlarını kontrol eder |
strictPropertyInitialization | Class alanlarının constructor'da başlatılmasını ister |
strictBuiltinIteratorReturn | Yerleşik iterator'ların dönüş değerini any yerine undefined sayar |
noImplicitThis | Tipi belirsiz this kullanımını hata sayar |
useUnknownInCatchVariables | catch (error) içindeki error'u any yerine unknown yapar |
alwaysStrict | Çıktıya JavaScript'in "use strict" modunu uygular |
Bayrak listesi TSConfig referansındaki strict ailesidir.4 En çok fark edeceğiniz ikisi noImplicitAny ve strictNullChecks'tir:
function getProduct(id) {}
// Hata: Parameter 'id' implicitly has an 'any' type.
try {
await fetchProducts();
} catch (error) {
console.log(error.message);
// Hata: 'error' is of type 'unknown'.
}TypeScript 6.0 ile strict varsayılan olarak açık hale geldi, TypeScript 7 de bu varsayılanı korudu.56 Yine de dosyaya "strict": true yazmak niyetinizi açıkça gösterir. Eski bir projeyi taşırken bile strict'i tamamen kapatmak yerine bayrakları tek tek açın.
strict'e Ek Bayraklar
noUncheckedIndexedAccess
strict'in parçası değildir ama en faydalı ek bayraktır. Dizi elemanına ya da index signature'lı bir nesneye erişimin sonucuna undefined ekler.7 Dizinin boş olabileceğini unutmanızı engeller:
const products: Product[] = await fetchProducts();
const first = products[0]; // Product | undefined
console.log(first.name);
// Hata: 'first' is possibly 'undefined'.
if (first) {
console.log(first.name); // artık Product
}Matt Pocock bu bayrağın aslında strict'e dahil olması gerektiğini söyler.8 TypeScript 7'de tsc --init de onu açık olarak üretir. Vite şablonunda ise kapalıdır; kendiniz eklemeniz gerekir.
Diğerleri
| Bayrak | Ne yapar | Öneri |
|---|---|---|
noUnusedLocals | Kullanılmayan yerel değişkeni hata sayar2 | Vite şablonunda açık |
noUnusedParameters | Kullanılmayan parametreyi hata sayar; _ ile başlayanlar hariç2 | Vite şablonunda açık |
noFallthroughCasesInSwitch | break'i unutulmuş case'leri yakalar | Vite şablonunda açık |
exactOptionalPropertyTypes | discountCode?: string alanına açıkça undefined atamayı yasaklar4 | İsteğe bağlı; sıkı ama gürültülü |
Matt Pocock ise noUnusedLocals gibi bayrakları "gürültülü" bulur ve yalnızca isteyenlerin eklemesini önerir.8 İkisi de geçerli bir seçim; ekip olarak birini seçin.
React Uygulaması İçin Ayarlar
Vite ya da Next.js kullanan bir uygulamada JavaScript'i TypeScript üretmez, bundler üretir. TypeScript yalnızca tip denetleyicisi olarak çalışır. Bu yüzden ayarlar buna göre seçilir:
| Ayar | Değer | Anlamı |
|---|---|---|
target | es2023 | Hangi JavaScript sürümünün söz dizimine izin verildiği |
lib | ["ES2023", "DOM"] | Hangi global API'lerin tipli olduğu; tarayıcı kodu için DOM şart9 |
module | esnext | Modern import/export; TypeScript 7'de varsayılan6 |
moduleResolution | bundler | Import'ları bundler gibi çözer; göreli import'ta uzantı istemez4 |
jsx | react-jsx | React 17+ JSX dönüşümü; her dosyada import React gerekmez10 |
noEmit | true | JavaScript dosyası üretmez, yalnızca kontrol eder |
verbatimModuleSyntax | true | type ile işaretlenmemiş import'lar kalır, işaretlenenler tamamen silinir; import type yazmaya zorlar11 |
isolatedModules | true | Tek dosyaya bakarak çeviren araçların (Oxc, SWC, esbuild) desteklemediği kodu hata sayar12 |
erasableSyntaxOnly | true | enum, parameter property gibi çalışma anı kodu üreten TypeScript söz dizimini yasaklar (TypeScript 5.8)13 |
skipLibCheck | true | node_modules içindeki .d.ts dosyalarını kontrol etmez; hız kazandırır8 |
verbatimModuleSyntax açıkken yalnızca tip olan import'ları şöyle yazarsınız:
import type { Product } from "./types";
import { formatPrice, type CartItem } from "./cart";Vite Şablonundaki Üç Dosya
npm create vite@latest -- --template react-ts (create-vite 9.2) üç dosya üretir:
| Dosya | Kapsam |
|---|---|
tsconfig.json | Kendisi dosya içermez ("files": []), diğer ikisine references verir |
tsconfig.app.json | src klasörü: tarayıcıda çalışan uygulama kodu, lib içinde DOM var |
tsconfig.node.json | vite.config.ts: Node'da çalışan yapılandırma, types içinde node var |
Uygulama kodu ile Node'da çalışan yapılandırma farklı ortamlarda çalıştığı için ayrı ayarlarla kontrol edilir. tsconfig.app.json'ın özü şöyledir:
{
"compilerOptions": {
"target": "es2023",
"lib": ["ES2023", "DOM"],
"module": "esnext",
"types": ["vite/client"],
"skipLibCheck": true,
"moduleResolution": "bundler",
"verbatimModuleSyntax": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",
"noUnusedLocals": true,
"noUnusedParameters": true,
"erasableSyntaxOnly": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"]
}Dosyada strict yok, çünkü şablonun kurduğu TypeScript 6.0'da zaten varsayılan. types: ["vite/client"] ise import.meta.env ve resim, CSS import'ları için tipleri ekler.14
references kullanan bir projede tip kontrolü tsc -b (--build) ile yapılır; bu komut referans verilen projeleri bulur ve doğru sırayla kontrol eder.15 Şablondaki build script'i de tsc -b && vite build'dir.
Hata
Kök dizinde npx tsc --noEmit çalıştırmak bu şablonda hiçbir dosyayı kontrol etmez, çünkü kök tsconfig.json boştur. Komut hata olsa bile başarıyla biter. npx tsc -b ya da npx tsc --noEmit -p tsconfig.app.json kullanın.
Next.js'te tsconfig
Next.js projesi create-next-app ile açıldığında tsconfig.json hazır gelir; var olan bir projede bir dosyayı .ts yapıp next dev çalıştırdığınızda Next.js dosyayı kendisi oluşturur.16 Üretilen dosyada strict, noEmit, moduleResolution: "bundler", jsx: "react-jsx", isolatedModules, @/* path alias'ı ve Next.js'in editör eklentisi ("plugins": [{ "name": "next" }]) bulunur. Ayrıca next-env.d.ts adında, elle düzenlenmemesi gereken bir tip dosyası üretilir.16
next build tip hatası varsa build'i durdurur. typescript.ignoreBuildErrors bu kontrolü kapatır; dokümantasyon bunu ancak tip kontrolünü başka bir yerde çalıştırıyorsanız önerir.16
Path Alias
../../../components/ProductCard gibi uzun göreli yollar yerine @/components/ProductCard yazmak için paths kullanılır:
{
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
}
}
}paths yalnızca TypeScript'e bu eşlemeyi anlatır; çıktıdaki import'ları değiştirmez. Eşlemeyi çalışma anında bundler'ın da bilmesi gerekir.4 Vite'ta bunun için vite.config.ts içinde resolve: { tsconfigPaths: true } ayarını açarsınız.14 Next.js paths'i kendisi okur.
@types Paketleri ve .d.ts
JavaScript ile yazılmış bir kütüphanenin tipleri declaration (.d.ts) dosyalarında durur. Birçok paket bu dosyaları kendisi getirir; getirmeyenler için topluluğun yazdığı tipler @types/ önekiyle yayımlanır (@types/react, @types/node).17 Bir paketi import ettiğinizde "Could not find a declaration file" hatası alıyorsanız önce npm install -D @types/<paket-adı> deneyin.
TypeScript 6.0'dan itibaren types ayarının varsayılanı boş dizidir: global tipler (örneğin Node'un process'i) artık kendiliğinden yüklenmez, "types": ["node"] gibi açıkça yazmanız gerekir.5 Vite şablonundaki types satırları bu yüzden var.
typescript-eslint
tsc tip hatalarını bulur; hatalı ama tip açısından geçerli kalıpları (örneğin beklenmeyen bir Promise) ise linter bulur. ESLint için TypeScript desteğini typescript-eslint sağlar. Tip bilgisini kullanan kurallar için recommendedTypeChecked ya da daha katı strictTypeChecked yapılandırması seçilir ve projectService açılır:18
// eslint.config.mjs
import js from "@eslint/js";
import { defineConfig } from "eslint/config";
import tseslint from "typescript-eslint";
export default defineConfig({
files: ["**/*.{ts,tsx}"],
extends: [
js.configs.recommended,
tseslint.configs.recommendedTypeChecked,
],
languageOptions: {
parserOptions: {
projectService: true,
},
},
});typescript-eslint, strictTypeChecked'i yalnızca ekibin önemli bir kısmı TypeScript'te deneyimliyse önerir.19
İpucu
CI'da Tip Kontrolü
Bundler tip kontrolü yapmadığı için, hatalı kodun ana dala girmemesini garanti etmenin yolu CI'da tsc çalıştırmaktır.21 Önce package.json'a bir script ekleyin:
{
"scripts": {
"typecheck": "tsc -b"
}
}Next.js ya da tek tsconfig'li bir projede değer tsc --noEmit olur. Ardından GitHub Actions iş akışı:22
# .github/workflows/ci.yml
name: CI
on:
pull_request:
push:
branches: [main]
jobs:
typecheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v7
with:
node-version: 24
cache: npm
- run: npm ci
- run: npm run typecheckPull request'te tip hatası varsa bu adım kırmızıya döner. Lint ve test adımlarını aynı job'a ekleyebilirsiniz.
Kendin Dene
Vite şablonunun
tsconfig.app.jsondosyasına"noUncheckedIndexedAccess": trueekleyin venpx tsc -bile kaç yeni hata çıktığına bakın.TS Playground'un TS Config menüsünden
strict'i kapatıp açın; aynı kodda hangi hataların kaybolduğunu izleyin.@/*alias'ını hempathshemresolve.tsconfigPathsile kurun; yalnızca birini açınca editörün vevite build'in nasıl davrandığını karşılaştırın.Bir dosyaya bilerek tip hatası koyup CI iş akışının kırmızıya döndüğünü görün.
Detaylı Öğrenmek İçin
Yazı: Matt Pocock'un TSConfig Cheat Sheet'i; bundler kullanan ve kullanmayan projeler için hazır bloklar.8
Kitap: Matt Pocock'un Total TypeScript Essentials kitabının "Configuring TypeScript" bölümü;
extends,lib,jsxve project references.23Resmi doküman: TSConfig Reference; her ayarın açıklaması ve örneği.4
Resmi doküman: typescript-eslint'in "Linting with Type Information" rehberi.18
Yazı: TypeScript 6.0 duyurusu; değişen varsayılanlar ve
baseUrlolmadanpathsyazımı.5
Kaynaklar
Proje kökü, `tsc`'nin dosyayı araması ve `extends` ile hazır temel ayarlar.
`include`, `extends`, `references`, `noUnusedLocals` ve `noUnusedParameters` açıklamaları.
Sıkılığın bir düğme gibi olması, `noImplicitAny` ve `strictNullChecks`.
Strict ailesindeki bayraklar, `exactOptionalPropertyTypes`, `moduleResolution: bundler` ve `paths`.
`strict` ve `types: []` varsayılanları, `baseUrl`'in kullanımdan kalkması ve `paths` yazımı.
7.0 varsayılanları, kaldırılan ayarlar ve `@typescript/typescript6` ile araç uyumluluğu.
Index signature erişimine `undefined` eklenmesi ve örneği.
: — Önerilen temel ve strict ayarlar, `noUncheckedIndexedAccess` ve `skipLibCheck` gerekçeleri.
React projesinde `lib` içinde `dom` ve geçerli bir `jsx` ayarı gerekmesi.
`react-jsx` ile `react/jsx-runtime` dönüşümü.
`type` işaretli import'ların silinip diğerlerinin olduğu gibi kalması.
Tek dosya çalışan dönüştürücülerin sınırları.
`--erasableSyntaxOnly` bayrağının tanıtımı ve gerekçesi.
Tip kontrolü yapılmaması, `isolatedModules` önerisi ve `vite/client` tipleri; `resolve.tsconfigPaths` için .
`references` ve `tsc -b`'nin projeleri doğru sırayla derlemesi.
Otomatik `tsconfig.json`, `next-env.d.ts`, build sırasında tip kontrolü ve `ignoreBuildErrors`.
`@types/` paketlerini kurmak ve kendi tipini getiren paketler.
`recommendedTypeChecked`, `strictTypeChecked` ve `projectService` ile örnek yapılandırma.
Hazır yapılandırmalar ve `strict-type-checked` için uyarı.
Desteklenen TypeScript sürüm aralığı.
: — `tsc --noEmit`'i linter gibi kullanmak ve CI'da tip kontrolü.
`actions/checkout`, `actions/setup-node`, npm önbelleği ve `npm ci`.
: — Temel yapılandırma, `strict`, `isolatedModules`, `verbatimModuleSyntax` ve project references.
Son güncelleme tarihi: 17 Ekim 2026
