TypeScript Best Practices: Tip Güvenliği ve Kod Kalitesi
TypeScript, JavaScript'e statik tip kontrolü ekleyerek kod kalitesini ve geliştirici deneyimini iyileştirir. Bu rehberde TypeScript best practice'lerini ve tip güvenliği tekniklerini anlatıyoruz.
Son güncelleme:TypeScript Neden Kullanılır?
TypeScript, JavaScript'in üst kümesidir (superset). Tüm JavaScript kodu geçerli TypeScript kodudur. Statik tip kontrolü ekler.
Tip güvenliği: Derleme zamanında tip hatalarını yakalar. Runtime hataları (undefined is not a function) azalır.
Geliştirici deneyimi: IDE autocomplete, refactoring, go-to-definition gibi özellikler tip bilgisi ile çalışır.
Büyük projeler: Kod tabanı büyüdükçe tip kontrolü, bakım ve refactoring'i kolaylaştırır. Ekip çalışmasını iyileştirir.
Tip Tanımlama Best Practices
interface vs type: Nesne şekilleri için interface kullanın. Union/intersection types için type kullanın. interface, extends ile genişletilebilir.
any kullanmaktan kaçının: any, tip kontrolünü devre dışı bırakır. unknown kullanın ve tip kontrolü yapın: if (typeof x === 'string') { ... }.
Strict mode: tsconfig.json'da strict: true ayarlayın. Bu, noImplicitAny, strictNullChecks, strictFunctionTypes gibi kontrolleri etkinleştirir.
Tip çıkarımı (Type Inference): Açık tip belirtmek yerine TypeScript'in tip çıkarımını kullanın. const name = 'John' (string olarak çıkarılır).
Literal types: string veya number yerine spesifik değerler kullanın: type Status = 'active' | 'inactive' | 'pending'.
Gelişmiş Tip Teknikleri
Generic types: Yeniden kullanılabilir, tip güvenli fonksiyonlar ve sınıflar oluşturun: function identity<T>(arg: T): T { return arg; }.
Conditional types: Tip koşullarına göre farklı tipler döndürün: type IsString<T> = T extends string ? true : false.
Mapped types: Mevcut tipleri dönüştürün: type Readonly<T> = { readonly [P in keyof T]: T[P]; }.
Utility types: TypeScript'in built-in utility types'larını kullanın: Partial, Required, Pick, Omit, Record, Exclude, Extract.
Template literal types: String manipulation ile tip güvenli string'ler oluşturun: type EventName = `on${Capitalize<string>}`.
React ile TypeScript
Props tanımlama: interface Props { name: string; age?: number; onClick: () => void; }. Opsiyonel props için ? kullanın.
useState: const [count, setCount] = useState<number>(0);. Tip çıkarımı genellikle yeterlidir: useState(0) (number olarak çıkarılır).
useRef: const inputRef = useRef<HTMLInputElement>(null);. DOM element referansları için doğru tip kullanın.
Event handlers: React.ChangeEvent<HTMLInputElement>, React.FormEvent<HTMLFormElement> gibi React event types'larını kullanın.
Children: React.ReactNode (genel) veya React.ReactElement (sadece element) kullanın. PropsWithChildren ile children prop'u ekleyin.
Hata Yönetimi ve Debugging
Type assertions: as keyword ile tip dönüşümü yapın: const value = input as string. Mümkün olduğunda type guard'ları tercih edin.
Type guards: typeof, instanceof, in operator'ları ve custom type guard fonksiyonları ile runtime tip kontrolü yapın.
Non-null assertion: ! operator ile null/undefined olmadığını belirtin: element!.value. Sadece kesin olduğunda kullanın.
tsconfig strictNullChecks: null ve undefined'ı açıkça handle edin. Optional chaining (?.) ve nullish coalescing (??) kullanın.
ESLint + TypeScript: @typescript-eslint plugin ile ek kurallar ekleyin. no-unused-vars, no-explicit-any gibi kuralları etkinleştirin.
Proje Yapılandırması
tsconfig.json: strict: true, target: 'ES2020', module: 'ESNext', moduleResolution: 'bundler', esModuleInterop: true ayarlayın.
Path aliases: baseUrl ve paths ile import path'lerini kısaltın: "@/*": ["src/*"]. import { Button } from '@/components/Button'.
Project references: Büyük projelerde project references ile incremental build yapın. tsconfig.json'da references array kullanın.
Monorepo: Turborepo veya Nx ile TypeScript monorepo yapılandırın. Shared types ve utilities için ortak paketler oluşturun.
Declaration files: .d.ts dosyaları ile JavaScript kütüphanelerine tip tanımları ekleyin. @types/* paketlerini kullanın.