Menu

TypeScript Best Practices: Önce ve Sonra ile 8 Kural

Gerçek hataları önleyen sekiz TypeScript alışkanlığı: strict'i açık tutun, any yerine unknown kullanın, tip çıkarımını çalıştırın, enum yerine union tercih edin, config'i satisfies ile kontrol edin, durumu discriminated union ile modelleyin, ! ve as kullanmaktan kaçının ve veriyi readonly yapın. Her biri çalıştırılabilir bir önce ve sonra örneğiyle gelir.

Bu sayfada çalıştırılabilir editörler var - düzenle, çalıştır ve sonucu anında gör.

Aşağıdaki kurallar, gerçek TypeScript kodunda en çok hatayı önleyenlerdir. Her biri önce yaygın sürümü, sonra daha iyisini, çalıştırabileceğiniz kodla gösterir. En önemlisi ilk kuraldır: any kullanmayı bırakın.

any Yerine unknown Kullanın

any, bir değer ve ondan hesaplanan her şey için tip kontrolünü kapatır. unknown da her değeri kabul eder, ama kullanmadan önce onu kontrol etmeniz gerekir; bu da kontrolü verinin programınıza girdiği yere koyar:

Sınırlar, tiplerin artık garanti olmadığı yerlerdir: JSON.parse, fetch yanıtları, localStorage, form girdileri, ortam değişkenleri ve diğer süreçlerden gelen mesajlar. Orada bir type guard ya da bir şema kütüphanesiyle doğrulayın, kodun geri kalanı tiplerine güvenebilir.

strict'i Açık Tutun

strict, TypeScript 7'de varsayılandır; kapatmayın. Onun dışarıda bıraktığı ve en çok hatayı yakalayan kontrolleri ekleyin:

{
    "compilerOptions": {
        "strict": true,
        "noUncheckedIndexedAccess": true,
        "noImplicitOverride": true,
        "noFallthroughCasesInSwitch": true
    }
}

noUncheckedIndexedAccess, arr[i] ve record[key] tiplerine undefined ekler; eksik bir indeks için döndürdükleri de budur. noImplicitOverride bir alt class metodunun override yazmasını sağlar, noFallthroughCasesInSwitch ise bir sonrakine akan bir case'i reddeder.

Tip Çıkarımını Çalıştırın

TypeScript'in bilemeyeceği şeyleri işaretleyin: fonksiyon parametreleri ve diğer modüllerin kullandığı fonksiyonların dönüş tipleri. Yerel değişkenleri ve callback parametrelerini tip çıkarımına bırakın. Gereksiz bir işaretleme yalnızca gürültü değildir; bir tipi değerden daha geniş yapabilir:

@ts-expect-error yorumu olmadan setStatus(annotated) TS2345 hatasıdır. Çıkarılan const, "active" literal tipini korur, bu yüzden kabul edilir. Bir tip eklemeden önce neyin çıkarıldığını görmek için editörünüzde değişkenin üzerine gelin.

Enum Yerine Union Tiplerini Tercih Edin

String literal'lerinden oluşan bir union, hiç kod üretmeden otomatik tamamlama ve eksiksizlik kontrolü verir. Değer listesine çalışma zamanında da ihtiyacınız varsa, tipi bir as const dizisinden türetin:

const ROLES = ["admin", "editor", "viewer"] as const;
type Role = (typeof ROLES)[number]; // "admin" | "editor" | "viewer"

function canEdit(role: Role): boolean {
  return role !== "viewer";
}

console.log(canEdit("editor"));     // true
console.log(ROLES.filter(canEdit)); // [ 'admin', 'editor' ]

canEdit("owner"); // error TS2345: Argument of type '"owner"' is not assignable to parameter of type '"admin" | "editor" | "viewer"'.

Bir enum Role { Admin, Viewer }, ters eşlemeli bir nesneye derlenir ve sayısal bir enum parametresi, enum'un listelemediği bir değeri tutsa bile herhangi bir number değişkenini kabul eder. Enum'lar Node'un type stripping'i altında da çalışamaz (TypeScript enum is not supported in strip-only mode). Artıları ve eksileri enum'lar sayfasında karşılaştırılır.

Config Nesnelerini satisfies ile Kontrol Edin

Bir nesneyi Record<string, Route> gibi geniş bir tiple işaretlemek değerlerini kontrol eder ama anahtarlarını unutur. satisfies aynı şeyi kontrol eder ve tam tipi korur:

Değişkenin tam olarak belirtilen tipe sahip olması gerektiğinde (bir fonksiyon parametresi, yeniden atayacağınız bir değer) işaretleme kullanın. Arama tabloları, route haritaları, tema token'ları ve diğer sabit nesneler için satisfies kullanın.

Durumu Discriminated Union ile Modelleyin

İsteğe bağlı alanları olan tek bir nesne, gerçekleşemeyecek durumlara izin verir: bir error ile birlikte loading: true ya da başarıdan sonra eksik data. Ortak bir etiketi paylaşan nesnelerden oluşan bir union yalnızca gerçek durumlara izin verir ve her dal yalnızca kendi alanlarını görür:

never satırı eksiksizlik kontrolüdür. Biri yeni bir durum ekleyip onu ele almayı unuttuğunda build o satırda kırılır:

Hata şudur: index.ts(14,13): error TS2322: Type '{ status: "cancelled"; }' is not assignable to type 'never'. Ele alınmayan durumu adıyla söyler. case "cancelled": ekleyin, kod derlenir.

! ve as Kullanmaktan Kaçının

Non-null assertion x! ve type assertion x as T, derleyiciye kontrolü bırakmasını söyler. İkisi de çalışma zamanında değeri değiştirmez, bu yüzden yanlış bir assertion daha sonra, nedeninden uzakta bir çökmeye dönüşür:

! yerine ?., ??, erken bir return ya da faydalı bir mesajla fırlatılan bir hata kullanın. as yerine değeri gerçekten test eden bir type guard kullanın. Her zaman güvenli olan tek assertion as const'tur, çünkü bir tipi yalnızca daraltır ve salt okunur yapar. İyi bir lint kurulumu (typescript-eslint'in no-non-null-assertion ve no-explicit-any kuralları) geri kalanını işaretler.

Veriyi readonly Yapın

Kodun değiştirmemesi gereken özellikleri ve dizileri readonly olarak işaretleyin. Derleyici bu durumda push, sort ve atamaları reddeder ve fonksiyonlar girdilerini değiştirmek yerine yeni değerler döndürür:

readonly yalnızca derleme zamanında ve yalnızca bir seviye derinlikte kontrol edilir: nesneyi çalışma zamanında dondurmaz. Yine de bu hataların çoğuna yol açan paylaşılan durumun kazara değiştirilmesini yakalamaya yeter.

Sıkça Sorulan Sorular

TypeScript'te any kullanmalı mıyım?

Uygulama kodunda neredeyse hiçbir zaman. any, değer ve ondan türetilen her şey için kontrolü kapatır. Tipini henüz bilmediğiniz değerler için unknown kullanın ve onları kontrollerle daraltın; any'yi nadir kaçış yolları için, nedenini açıklayan bir yorumla birlikte saklayın.

TypeScript'te her değişkene tip yazmalı mıyım?

Hayır. Yerel değişkenlerin ve callback parametrelerinin tipini TypeScript çıkarsın. Fonksiyon parametrelerini (çıkarılamazlar) ve export edilen fonksiyonların dönüş tiplerini işaretleyin; böylece fonksiyonun içindeki bir değişiklik public tipini sessizce değiştiremez.

TypeScript enum'ları kötü bir uygulama mı?

Yanlış değiller, ama birçok ekip onlardan kaçınır. Bir enum çalışma zamanı kodu üretir, Node'un type stripping'i altında çalışamaz ve sayısal bir enum parametresi, tuttuğu değer ne olursa olsun herhangi bir number değişkenini kabul eder. String literal'lerinden oluşan bir union ya da türetilmiş bir tipe sahip bir as const dizisi, hiç kod üretmeden aynı otomatik tamamlamayı ve kontrolleri verir.

as ile type assertion ne zaman kullanılmalı?

Yalnızca derleyicinin bilemeyeceği bir şeyi bildiğinizde ve tercihen bunu kanıtlayan bir kontrolün hemen ardından. as çalışma zamanında hiçbir değeri değiştirmez, bu yüzden {} as User derlenir ve sonra hiçbir name içermez. Çoğu durumda değeri test eden bir type guard daha güvenli bir araçtır.

Yeni bir TypeScript projesi için en iyi tsconfig ayarları nelerdir?

strict'i açık tutun (TypeScript 7'nin varsayılanı) ve noUncheckedIndexedAccess ekleyin. Birçok proje ayrıca noImplicitOverride, noFallthroughCasesInSwitch ve verbatimModuleSyntax seçeneklerini açar. tsc --init'in yazdığı config, diğerlerinin yanında strict, noUncheckedIndexedAccess, exactOptionalPropertyTypes ve verbatimModuleSyntax ayarlar.

Coddy programming languages illustration

Coddy ile kodlamayı öğren

BAŞLA