İçeriğe geç
Yazılım ve Teknoloji

Typescript’te Any Kullanımından Kurtulma Rehberi

Rıfat Akarca 👁️ 3 okunma 📅 ⏱️ 13 dk okuma
İçindekiler

TypeScript kullanmaya başlamanın temel amacı, JavaScript koduna statik tip güvenliği kazandırmaktır. Buna rağmen projelerde sıkça any ile karşılaşırız. Bilinmeyen bir API yanıtı, karmaşık bir kütüphane tipi veya yetişmesi gereken bir görev derken any, en hızlı çözüm gibi görünebilir.

Sorun şu ki any, TypeScript’in bizi koruyan kontrollerini büyük ölçüde devre dışı bırakır. Kod derlenir ancak çalışma zamanında ortaya çıkabilecek hatalar gizlenir. Üstelik bir noktada kullanılan any, zamanla fonksiyonlara ve uygulamanın diğer katmanlarına yayılabilir.

Bu rehberde TypeScript’te any kullanımından kurtulmak için uygulanabilecek yöntemleri gerçekçi örneklerle inceleyeceğiz. unknown, type guard, generic, union type ve doğru tip modelleme gibi araçları nerede kullanmanız gerektiğini adım adım ele alacağız.

TypeScript’te any Nedir?

any, bir değerin tipi üzerinde TypeScript denetimini devre dışı bırakır. any olarak tanımlanan bir değişken üzerinde hemen her işlem yapılabilir.

let kullanici: any = {
  isim: "Rıfat",
};

console.log(kullanici.isim);
console.log(kullanici.adres.sehir);
kullanici.calis();

TypeScript bu kodu kabul eder. Ancak adres veya calis gerçekte bulunmuyorsa uygulama çalışma zamanında hata verir.

any kullanıldığında aşağıdaki korumaların önemli bir bölümü kaybedilir:

  • Özellik adı kontrolü
  • Fonksiyon parametresi kontrolü
  • Dönüş tipi kontrolü
  • Otomatik kod tamamlama
  • Güvenli yeniden adlandırma
  • Bazı refactoring kontrolleri
  • Ulaşılması imkânsız durumların tespiti

Başka bir ifadeyle any, TypeScript dosyasının içinde JavaScript gibi kontrolsüz bir alan oluşturur.

any Neden Bu Kadar Kolay Yayılır?

any değerinin en tehlikeli özelliklerinden biri, başka değişkenlere ve fonksiyonlara kolayca aktarılmasıdır.

function kullaniciGetir(): any {
  return {
    id: 1,
    name: "Rıfat",
  };
}

const kullanici = kullaniciGetir();
const kullaniciId = kullanici.id;
const profil = kullanici.profile;

Burada kullanici, kullaniciId ve profil üzerinden yapılan işlemler yeterince denetlenmez. Fonksiyonun dönüş değeri uygulamanın farklı noktalarında kullanıldıkça güvenli olmayan alan büyür.

Bu nedenle amaç yalnızca dosyalardaki any kelimelerini silmek değil, güvenilmeyen verinin sisteme girdiği sınırları bulup orada doğrulama yapmaktır.

Her any Kullanımı Hatalı mı?

Pratikte bazı geçiş süreçlerinde geçici olarak any kullanılması gerekebilir. Örneğin büyük bir JavaScript projesi TypeScript’e taşınırken bütün tipleri aynı anda hazırlamak mümkün olmayabilir.

Ancak böyle durumlarda any:

  • Geçici olmalı
  • Dar bir alanda tutulmalı
  • Neden kullanıldığı açıklanmalı
  • Uygulama geneline yayılmamalı
  • Kaldırılması için takip görevi oluşturulmalı

Kalıcı çözüm olarak kullanılan any, teknik borcu görünmez hâle getirir. Bilinmeyen bir veriyle çalışıyorsak çoğu zaman daha doğru seçenek unknown türüdür.

1. any Yerine unknown Kullanın

unknown, değerin tipini bilmediğimizi ifade eder. any ile arasındaki temel fark, değeri kullanmadan önce tipini kontrol etmemizi zorunlu kılmasıdır.

Güvensiz any örneği

function degeriYazdir(deger: any) {
  console.log(deger.toUpperCase());
}

degeriYazdir(42);

Bu kod derlenir fakat çalışma zamanında hata verir.

Güvenli unknown örneği

function degeriYazdir(deger: unknown) {
  if (typeof deger === "string") {
    console.log(deger.toUpperCase());
    return;
  }

  console.log("Metin olmayan bir değer gönderildi.");
}

unknown kullanıldığında TypeScript, tip kontrolü yapılmadan toUpperCase çağrılmasına izin vermez.

Kısa kural şudur:

  • Değerin tipini gerçekten bilmiyorsanız unknown kullanın.
  • Değerin tipini biliyorsanız uygun interface veya type tanımlayın.
  • Tip güvenliğini bilinçli olarak tamamen kapatmak istemiyorsanız any kullanmayın.

2. Veri Modelleri İçin interface veya type Tanımlayın

API yanıtları ve nesneler için any kullanmak yerine beklenen veri yapısını açıkça tanımlayın.

Önce

async function kullaniciGetir(): Promise<any> {
  const yanit = await fetch("/api/users/1");
  return yanit.json();
}

Sonra

interface Kullanici {
  id: number;
  ad: string;
  email: string;
  aktif: boolean;
}

async function kullaniciGetir(): Promise<Kullanici> {
  const yanit = await fetch("/api/users/1");
  return yanit.json();
}

Bu değişiklik kod tamamlama ve derleme zamanı kontrolü sağlar. Ancak önemli bir ayrıntı vardır: fetch sonucuna Kullanici tipi vermek, dışarıdan gelen verinin gerçekten bu yapıda olduğunu kanıtlamaz.

API yanıtı güvenilmeyen bir dış veri kaynağıdır. Kritik veriler çalışma zamanında ayrıca doğrulanmalıdır.

3. JSON.parse Sonucunu Doğrulayın

Dışarıdan gelen JSON verisini doğrudan güvenilir bir tipe dönüştürmek risklidir.

Aşağıdaki kullanım TypeScript’i ikna eder ancak veriyi doğrulamaz:

const kullanici = JSON.parse(veri) as Kullanici;

Daha güvenli yaklaşım, sonucu önce unknown kabul edip kontrol etmektir:

interface Kullanici {
  id: number;
  ad: string;
}

function kullaniciMi(deger: unknown): deger is Kullanici {
  if (typeof deger !== "object" || deger === null) {
    return false;
  }

  const nesne = deger as Record<string, unknown>;

  return (
    typeof nesne.id === "number" &&
    typeof nesne.ad === "string"
  );
}

const sonuc: unknown = JSON.parse(veri);

if (!kullaniciMi(sonuc)) {
  throw new Error("Geçersiz kullanıcı verisi");
}

console.log(sonuc.ad);

Doğrulama sonrasında TypeScript, sonuc değerinin Kullanici olduğunu bilir.

Daha büyük veri modellerinde manuel kontroller yerine çalışma zamanı şema doğrulama kütüphaneleri kullanılabilir. Ancak temel prensip değişmez:

Dış veri, TypeScript tipi atanarak değil çalışma zamanında doğrulanarak güvenilir hâle gelir.

4. Type Guard Fonksiyonları Oluşturun

Type guard, bir değerin belirli bir tipe ait olup olmadığını kontrol eden fonksiyondur.

Basit bir örnek:

function metinMi(deger: unknown): deger is string {
  return typeof deger === "string";
}

function buyukHarfleYaz(deger: unknown) {
  if (metinMi(deger)) {
    console.log(deger.toUpperCase());
  }
}

Nesne yapıları için de type guard kullanılabilir:

interface Urun {
  id: number;
  isim: string;
  fiyat: number;
}

function urunMu(deger: unknown): deger is Urun {
  if (typeof deger !== "object" || deger === null) {
    return false;
  }

  const nesne = deger as Record<string, unknown>;

  return (
    typeof nesne.id === "number" &&
    typeof nesne.isim === "string" &&
    typeof nesne.fiyat === "number"
  );
}

Aynı veri yapısı farklı yerlerde kontrol ediliyorsa type guard fonksiyonları tekrar eden doğrulama kodunu azaltır.

5. Tip İddiası Yerine Tip Daraltma Kullanın

Type assertion, yani tip iddiası, TypeScript’e “bu değerin tipini benden daha iyi bildiğimi kabul et” demektir.

const deger = veri as Kullanici;

Bu ifade çalışma zamanında hiçbir kontrol yapmaz. Veri Kullanici yapısına uymasa bile TypeScript kodu kabul eder.

Mümkün olduğunda tip daraltma kullanılmalıdır:

function isle(deger: unknown) {
  if (typeof deger === "string") {
    console.log(deger.toUpperCase());
    return;
  }

  if (typeof deger === "number") {
    console.log(deger.toFixed(2));
  }
}

TypeScript aşağıdaki kontroller üzerinden tip daraltabilir:

  • typeof
  • instanceof
  • in
  • Eşitlik kontrolleri
  • Kullanıcı tanımlı type guard fonksiyonları
  • Ayırt edici alanlara sahip union type yapıları

Tip iddiası yalnızca çalışma zamanındaki yapının başka bir yolla bilindiği dar ve kontrollü alanlarda tercih edilmelidir.

6. Birden Fazla Olasılık İçin Union Type Kullanın

Bir değişken birden fazla geçerli tip alabiliyorsa any yerine union type kullanılabilir.

Önce

function kimlikYazdir(id: any) {
  console.log(id);
}

Sonra

type Kimlik = string | number;

function kimlikYazdir(id: Kimlik) {
  console.log(id);
}

Fonksiyon içinde tipe özel işlem yapılacaksa değer daraltılır:

function kimlikFormati(id: string | number): string {
  if (typeof id === "number") {
    return id.toString().padStart(6, "0");
  }

  return id.toUpperCase();
}

Union type, fonksiyonun kabul ettiği değerleri açıkça gösterir ve beklenmeyen tipleri engeller.

7. Durum Modellemek İçin Discriminated Union Kullanın

API veya arayüz durumlarını any içeren geniş nesnelerle modellemek yerine ayırt edici union yapısı kullanılabilir.

Güvensiz model

interface ApiDurumu {
  status: string;
  data?: any;
  error?: any;
}

Bu modelde başarılı durumda data, hatalı durumda error bulunması gerektiği garanti edilmez.

Daha güvenli model

type ApiDurumu<T> =
  | { status: "idle" }
  | { status: "loading" }
  | { status: "success"; data: T }
  | { status: "error"; error: Error };

function sonucuGoster(durum: ApiDurumu<Kullanici>) {
  switch (durum.status) {
    case "idle":
      return "Henüz istek yapılmadı.";

    case "loading":
      return "Yükleniyor...";

    case "success":
      return durum.data.ad;

    case "error":
      return durum.error.message;
  }
}

status alanı kontrol edildiğinde TypeScript diğer alanları otomatik olarak daraltır.

Bu yapı imkânsız durumların modellenmesini de engeller. Örneğin aynı nesnenin hem başarılı hem hatalı görünmesi mümkün olmaz.

8. Tekrar Kullanılabilir Kodlarda Generic Kullanın

Bazı geliştiriciler farklı tiplerle çalışabilen fonksiyonlarda any kullanır:

function ilkEleman(liste: any[]): any {
  return liste[0];
}

const sonuc = ilkEleman(["a", "b", "c"]);

Fonksiyon, giriş ile çıkış arasındaki tip ilişkisini kaybeder. Generic kullanarak bu ilişkiyi koruyabiliriz:

function ilkEleman<T>(liste: T[]): T | undefined {
  return liste[0];
}

const metin = ilkEleman(["a", "b", "c"]);
const sayi = ilkEleman([10, 20, 30]);

TypeScript ilk çağrıda dönüş tipini string | undefined, ikinci çağrıda number | undefined olarak çıkarır.

Bir API yanıtı da generic olarak modellenebilir:

interface ApiYaniti<T> {
  basarili: boolean;
  veri: T;
}

interface Urun {
  id: number;
  isim: string;
}

const yanit: ApiYaniti<Urun[]> = {
  basarili: true,
  veri: [
    {
      id: 1,
      isim: "Klavye",
    },
  ],
};

Generic yapılar, any kullanmadan esnek ve tekrar kullanılabilir kod yazmayı sağlar.

9. Nesne Sözlüklerinde Record Kullanın

Anahtarları dinamik olan nesnelerde any yerine Record kullanılabilir.

Önce

const ayarlar: any = {};

ayarlar.tema = "koyu";
ayarlar.sayfaBoyutu = 20;

Değerlerin aynı tipte olması bekleniyorsa:

const etiketler: Record<string, string> = {
  dil: "tr",
  tema: "koyu",
};

Değerler gerçekten farklı ve başlangıçta bilinmiyorsa:

const veri: Record<string, unknown> = {
  ad: "Rıfat",
  yas: 30,
  aktif: true,
};

Bir değeri kullanmadan önce daraltma yapılır:

const ad = veri.ad;

if (typeof ad === "string") {
  console.log(ad.toUpperCase());
}

Record<string, unknown>, dinamik nesne yapılarında Record<string, any> kullanımına göre daha güvenlidir.

10. Callback Tiplerini Açıkça Tanımlayın

Callback parametrelerinde kullanılan any, fonksiyonun giriş ve çıkış ilişkisini belirsizleştirir.

Önce

function veriyiIsle(callback: any) {
  callback("tamamlandı");
}

Sonra

type IslemCallback = (mesaj: string) => void;

function veriyiIsle(callback: IslemCallback): void {
  callback("tamamlandı");
}

Daha esnek bir yapı gerekiyorsa generic kullanılabilir:

function donustur<T, R>(
  deger: T,
  callback: (girdi: T) => R,
): R {
  return callback(deger);
}

const uzunluk = donustur("TypeScript", (metin) => metin.length);

Bu fonksiyon giriş ve dönüş tipleri arasındaki ilişkiyi kaybetmeden farklı veri türleriyle çalışabilir.

11. DOM Olaylarını Doğru Tiplerle Kullanın

Frontend kodunda event parametrelerine sıkça any verilir:

function degistir(event: any) {
  console.log(event.target.value);
}

Standart DOM kullanımında uygun olay tipi ve güvenli hedef kontrolü kullanılabilir:

function degistir(event: Event) {
  const hedef = event.target;

  if (hedef instanceof HTMLInputElement) {
    console.log(hedef.value);
  }
}

Framework kullanılıyorsa framework’ün sunduğu olay tipleri tercih edilmelidir. Örneğin React içinde:

import type { ChangeEvent } from "react";

function degistir(event: ChangeEvent<HTMLInputElement>) {
  console.log(event.currentTarget.value);
}

currentTarget, olay dinleyicisinin bağlandığı elemanı ifade ettiği için birçok durumda target kullanımından daha güvenli olabilir.

12. Hata Yakalamada unknown Kullanın

JavaScript’te throw ile her tür değer fırlatılabilir. Bu nedenle catch bloğundaki değerin her zaman Error olduğunu varsaymak güvenli değildir.

try {
  riskliIslem();
} catch (hata: any) {
  console.log(hata.message);
}

Daha güvenli kullanım:

try {
  riskliIslem();
} catch (hata: unknown) {
  if (hata instanceof Error) {
    console.error(hata.message);
  } else {
    console.error("Bilinmeyen hata:", hata);
  }
}

Farklı kaynaklardan gelen hatalar için tekrar kullanılabilir bir yardımcı fonksiyon hazırlanabilir:

function hataMesajiAl(hata: unknown): string {
  if (hata instanceof Error) {
    return hata.message;
  }

  if (typeof hata === "string") {
    return hata;
  }

  return "Bilinmeyen bir hata oluştu.";
}

13. Üçüncü Taraf Paketlerde Eksik Tipleri Tamamlayın

Bazı JavaScript paketleri TypeScript tipleri sunmayabilir. Böyle bir durumda bütün paketi any kabul etmek kısa vadede kolay görünür.

Öncelikle şu seçenekler değerlendirilmelidir:

  1. Paketin kendi tip tanımları olup olmadığını kontrol edin.
  2. Topluluk tarafından yayımlanan tip paketini araştırın.
  3. Paket yerine aktif olarak tip desteği sunan bir alternatif değerlendirin.
  4. Yalnızca kullandığınız API yüzeyi için yerel tip bildirimi yazın.

Örnek bir modül bildirimi:

declare module "eski-paket" {
  export interface Ayarlar {
    timeout?: number;
  }

  export function baslat(ayarlar?: Ayarlar): void;
}

Bütün modülü kontrolsüz any olarak tanımlamak yerine yalnızca kullanılan fonksiyonları modellemek daha güvenli bir geçiş sağlar.

14. any[] Yerine Doğru Dizi Tipini Kullanın

Dizi elemanlarının yapısı biliniyorsa açık bir tip tanımlanmalıdır:

interface Siparis {
  id: number;
  toplam: number;
}

const siparisler: Siparis[] = [];

Birden fazla eleman tipi destekleniyorsa union kullanılabilir:

const degerler: Array<string | number> = [
  "aktif",
  42,
];

Elemanların tipi gerçekten bilinmiyorsa:

const veriler: unknown[] = [];

Bu durumda diziden alınan her değer kullanılmadan önce kontrol edilmelidir.

15. Fonksiyon Dönüş Tiplerini Belirginleştirin

TypeScript birçok dönüş tipini otomatik çıkarabilir. Ancak özellikle dışarıya açılan fonksiyonlarda dönüş tipini açıkça yazmak, yanlışlıkla any yayılmasını ve beklenmeyen API değişikliklerini önleyebilir.

interface Profil {
  id: number;
  ad: string;
}

function profilOlustur(id: number, ad: string): Profil {
  return {
    id,
    ad,
  };
}

Asenkron fonksiyonlarda Promise tipi belirtilmelidir:

async function profiliGetir(id: number): Promise<Profil> {
  const yanit = await fetch(`/api/profiles/${id}`);
  const veri: unknown = await yanit.json();

  return profiliDogrula(veri);
}

Dış veri doğrulanarak uygulamanın tip güvenli alanına alınmalıdır.

16. never ile Eksik Durumları Yakalayın

Union type kullanan kodlarda yeni bir durum eklendiğinde bütün koşulların güncellendiğinden emin olmak için never kullanılabilir.

type Durum =
  | { tip: "bekliyor" }
  | { tip: "tamamlandi"; sonuc: string }
  | { tip: "hata"; mesaj: string };

function assertNever(deger: never): never {
  throw new Error(`Beklenmeyen durum: ${JSON.stringify(deger)}`);
}

function durumMetni(durum: Durum): string {
  switch (durum.tip) {
    case "bekliyor":
      return "İşlem bekliyor.";

    case "tamamlandi":
      return durum.sonuc;

    case "hata":
      return durum.mesaj;

    default:
      return assertNever(durum);
  }
}

Union yapısına yeni bir seçenek eklendiğinde ve switch güncellenmediğinde TypeScript hata üretir.

Bu yöntem, any kullanarak bütün durumları kontrolsüz bırakmaktan çok daha güvenlidir.

TypeScript Ayarlarıyla Gizli any Kullanımlarını Bulmak

Projede açıkça yazılmayan ancak TypeScript tarafından dolaylı olarak any kabul edilen değerler olabilir.

tsconfig.json dosyasında sıkı kontroller etkinleştirilebilir:

{
  "compilerOptions": {
    "strict": true,
    "noImplicitAny": true,
    "useUnknownInCatchVariables": true,
    "noUncheckedIndexedAccess": true
  }
}

strict

Birden fazla sıkı tip kontrolünü birlikte etkinleştirir. Yeni TypeScript projelerinde güçlü bir başlangıç sağlar.

noImplicitAny

TypeScript’in tipini çıkaramadığı parametreleri sessizce any olarak kabul etmesini engeller.

function topla(a, b) {
  return a + b;
}

noImplicitAny etkin olduğunda a ve b parametreleri için tip tanımlanması gerekir:

function topla(a: number, b: number): number {
  return a + b;
}

useUnknownInCatchVariables

catch bloğundaki hata değerinin daha güvenli biçimde unknown olarak ele alınmasını sağlar.

noUncheckedIndexedAccess

Dizi veya sözlük içinden alınan değerin bulunmama ihtimalini tipe ekler:

const isimler = ["Ada", "Linus"];
const ilkIsim = isimler[0];
// string | undefined

Bu ayar doğrudan any ile ilgili olmasa da kontrolsüz varsayımları azaltır.

ESLint ile any Kullanımını Kontrol Etmek

Derleyici ayarlarına ek olarak lint kurallarıyla açık any kullanımları tespit edilebilir.

Örneğin TypeScript ESLint ekosistemindeki ilgili kurallar şu sorunları bulmaya yardımcı olabilir:

  • Açıkça yazılmış any tipleri
  • Güvensiz özellik erişimleri
  • Güvensiz fonksiyon çağrıları
  • Güvensiz atamalar
  • Güvensiz dönüş değerleri

Bu kontrollerin amacı geliştiriciyi yavaşlatmak değil, any değerinin uygulamanın güvenli bölgelerine fark edilmeden yayılmasını önlemektir.

Mevcut ve büyük bir projede bütün kuralları aynı anda hata seviyesinde açmak yüzlerce uyarıya yol açabilir. Kurallar aşamalı olarak etkinleştirilebilir.

Büyük Bir Projede any Nasıl Temizlenir?

Mevcut projedeki bütün any kullanımlarını tek bir değişiklikte kaldırmak genellikle gerçekçi değildir. Daha güvenli bir geçiş planı uygulanabilir.

1. Kullanım alanlarını bulun

Açık any, any[], Promise<any> ve Record<string, any> kullanımlarını listeleyin. Güvensiz tip iddialarını da inceleyin.

2. Kod sınırlarını önceliklendirin

İlk olarak verinin sisteme girdiği noktaları ele alın:

  • API yanıtları
  • Form verileri
  • Ortam değişkenleri
  • Dosya içerikleri
  • Webhook istekleri
  • Veri tabanı sonuçları
  • Üçüncü taraf paketler

Bu noktalarda unknown ve çalışma zamanı doğrulaması kullanmak, any değerinin içeride yayılmasını engeller.

3. İş açısından kritik alanlara odaklanın

Ödeme, yetkilendirme, sipariş ve kullanıcı verileri gibi hata maliyeti yüksek alanlar önce temizlenmelidir.

4. Geniş tipleri küçük parçalara ayırın

Tek bir büyük interface tanımlamak yerine kullanım senaryosuna uygun daha küçük tipler oluşturun.

interface KullaniciOzeti {
  id: number;
  ad: string;
}

interface KullaniciDetayi extends KullaniciOzeti {
  email: string;
  roller: string[];
}

5. Her değişiklikte kapsamı daraltın

Dokunulan dosyada yeni any eklememek ve mevcut kullanımlardan birkaçını kaldırmak sürdürülebilir ilerleme sağlar.

6. Kontrolleri aşamalı olarak sıkılaştırın

Önce uyarı seviyesinde kullanılan lint kuralları, sorunlar azaldıkça hata seviyesine taşınabilir. strict ayarları da proje yapısına göre aşamalı biçimde etkinleştirilebilir.

7. Geçici istisnaları belgeleyin

Kaldırılamayan any kullanımlarında nedenini ve kaldırılma koşulunu açıklayın:

// TODO: Eski servis yeni yanıt şemasına geçtiğinde bu tip kaldırılacak.
const eskiServisYaniti: any = await eskiServisCagir();

Bu çözüm ideal değildir ancak gerekçesiz ve görünmez teknik borçtan daha yönetilebilirdir.

any Yerine Ne Kullanmalıyım?

İhtiyaçÖnerilen Tip
Değerin tipi bilinmiyorunknown
Birden fazla geçerli tip varUnion type
Aynı yapı farklı tiplerle çalışıyorGeneric
Dinamik anahtarlı nesneRecord<string, T>
Belirli nesne yapısıinterface veya type
Sabit seçeneklerLiteral union veya enum
Hiçbir zaman değer dönmeznever
Değer olmayabilirT | undefined veya T | null
Callback tanımlanacakAçık fonksiyon tipi
Dış veri kullanılacakunknown ve çalışma zamanı doğrulaması

Sık Yapılan Hatalar

any yerine her yerde as kullanmak

const veri = sonuc as Kullanici;

Bu değişiklik gerçek tip güvenliği sağlamaz. Sadece TypeScript’in uyarısını susturur.

Çok geniş interface tanımlamak

Her alanı opsiyonel ve geniş tipte tanımlamak, any kullanımını kaldırsa bile benzer belirsizlik üretir.

interface Veri {
  id?: string | number;
  deger?: string | number | object;
}

Tipler kullanım senaryosunu açık biçimde modellemelidir.

Dış veriye doğrudan güvenmek

API dokümantasyonu doğru olsa bile ağdan gelen veri çalışma zamanında beklenen yapıdan farklı olabilir. Kritik alanlarda doğrulama yapılmalıdır.

Generic içinde any kullanmak

function isle<T extends Record<string, any>>(deger: T) {
  return deger;
}

İhtiyaca göre Record<string, unknown> veya daha açık bir constraint tercih edilebilir.

Tip hatasını çözmek yerine susturmak

Bir tip hatası çoğu zaman veri modelindeki gerçek bir uyumsuzluğu gösterir. Hemen any veya çift tip iddiası kullanmadan önce hatanın kaynağı araştırılmalıdır.

Sonuç

TypeScript’te any kullanımından kurtulmak, bütün any ifadelerini rastgele başka tiplerle değiştirmek değildir. Asıl amaç, verinin ne olduğunu doğru modellemek ve bilinmeyen veriyi kullanmadan önce doğrulamaktır.

Temel yaklaşımı şu şekilde özetleyebiliriz:

  • Bilinmeyen değerlerde any yerine unknown kullanın.
  • Nesneler için açık veri modelleri oluşturun.
  • Birden fazla geçerli tip için union type tercih edin.
  • Giriş ve çıkış ilişkisini korumak için generic kullanın.
  • Dış verileri çalışma zamanında doğrulayın.
  • Tip iddialarını dar ve kontrollü alanlarla sınırlayın.
  • strict ve noImplicitAny kontrollerini etkinleştirin.
  • Büyük projelerde dönüşümü aşamalı olarak yönetin.

any yazmak kısa vadede birkaç dakika kazandırabilir. Doğru tipleri oluşturmak ise hata ayıklama süresini azaltır, refactoring işlemlerini güvenli hâle getirir ve kodun ne yaptığını ekipteki herkes için daha anlaşılır kılar.

Sıkça Sorulan Sorular

TypeScript’te any neden kullanılmamalı?

any, özellik erişimi, parametre ve dönüş tipi gibi birçok TypeScript kontrolünü devre dışı bırakır. Bu nedenle derleme aşamasında bulunabilecek hatalar çalışma zamanına taşınabilir.

any ile unknown arasındaki fark nedir?

Her iki tip de farklı değerleri kabul edebilir. Ancak unknown değerini kullanmadan önce tip kontrolü yapılması gerekir. any ise kontrol olmadan işlem yapılmasına izin verir.

as kullanmak any sorununu çözer mi?

Hayır. Type assertion çalışma zamanında doğrulama yapmaz. Yalnızca TypeScript’e değerin belirtilen tipte olduğunu varsaymasını söyler.

API yanıtına interface vermek yeterli mi?

Hayır. Interface yalnızca derleme zamanı kontrolü sağlar. Dışarıdan gelen veri kritikse çalışma zamanında ayrıca doğrulanmalıdır.

Generic ile any arasındaki fark nedir?

any tip bilgisini kaybeder. Generic ise giriş ve çıkış tipleri arasındaki ilişkiyi koruyarak farklı tiplerle güvenli biçimde çalışmayı sağlar.

Mevcut projedeki bütün any kullanımları bir anda kaldırılmalı mı?

Genellikle hayır. API, form ve dosya gibi veri giriş noktalarından başlanarak iş açısından kritik alanlar önceliklendirilebilir. Kontroller aşamalı olarak sıkılaştırılmalıdır.