ProgramlamaTypeScript geliştirici

TypeScript'te işaretler düzeyinde fonksiyon aşırı yüklemesini (overload) nasıl uygulayıp doğru bir şekilde tip verebilirim? Birden fazla fonksiyon gövdesi neden kullanılamaz ve fonksiyon gövdesindeki parametrelerin tipleriyle ne olur? Pratik kullanım senaryoları ve en sık yapılan hataları belirtin.

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

Fonksiyon aşırı yüklemesi, aynı isimde farklı parametre alabilen ve farklı dönüş değerine sahip bir fonksiyon oluşturmaya olanak tanır. C# veya Java gibi diğer dillerde, bir isimle, ancak farklı tiplerde veya argüman sayılarında birkaç fonksiyon tanımlanabilir. TypeScript, bu mekanizmayı tipler düzeyinde aşırı yükleme ile yaklaştırır, ancak fonksiyonun gövdesi her zaman tek olmalıdır.

Meselenin kökeni, JavaScript'te tip veya parametre sayısına dayalı aşırı yüklemenin yerel bir desteğinin olmamasıdır. TypeScript çıktıkça, aşırı yükleme, fonksiyonun birkaç imzasının ardışık olarak tanımlanması ve bunların altında el ile hangi tipin çalışıldığı ile ilgili tek bir uygulama ile simüle edilmektedir.

Problemin ortaya çıkması, belirtilen imzalara uygunluk sağlanmadığında olur: TypeScript, fonksiyon gövdesindeki parametrelere en genel tipi (tüm parametre tiplerinin bir birleşimi) atar ve programcının kontroller ve tipi koruyucuları (type guards) yapması gerekir.

Çözüm: Aşırı yüklemeleri açık imzalar ile sıkı bir şekilde tip vermek, union tiplerle ve tipi koruyucularla iyi çalışmak, davranışı doğru bir şekilde dökümante etmek.

Kod örneği:

function format(value: string): string; function format(value: number, locale: string): string; function format(value: any, locale?: string): string { if (typeof value === 'number') { return value.toLocaleString(locale); } return value.trim(); } format(' hello '); // 'hello' format(123456, 'ru-RU'); // '123 456'

Ana özellikler:

  • Ardışık olarak birden fazla hizmet aşırı yükleme imzası, altında tek bir uygulama.
  • Gövde içinde parametrelerle çalışırken ya union-tip ya da any/unknown kullanılır.
  • Gövde tipi, yukarıdaki imzalardan daha geniş/evrenseldir.

Sürpriz Sorular.

C#'taki gibi aynı isme ve farklı gövdelere sahip birden fazla fonksiyon tanımlamak mümkün mü?

Hayır. TypeScript'te (ve JavaScript'te) gerçekte yalnızca bu isimde bir fonksiyon bulunmaktadır. Aşırı yüklemeler, yalnızca derleyici için tip düzeyinde çalışıyor, ancak yalnızca bir fonksiyon gövdesi vardır.

Aşırı yükleme imzalarından sonra en genel parametreleri içeren bir imza uygulanmazsa ne olur?

TypeScript, derleme hatası verecektir. Her zaman tüm olası aşırı yükleme türlerini kapsayan bir fonksiyon-gerçekleştirme bulunmalıdır.

function foo(a: string): string; function foo(a: number): number; // gövde yok — hata

Gövde içinde yalnızca belirli bir imzaya özgü özellikleri kullanabilir miyim?

Hayır, yalnızca tip kontrolü (type guard) veya tip çıkarımı sonrasında. Aksi takdirde TypeScript, bu özellikleri doğrudan kullanmanıza izin vermeyecektir, çünkü hangi imzanın çağrıldığı bilinmemektedir.

function bar(x: string): number; function bar(x: number): number; function bar(x: string | number): number { if (typeof x === 'string') return x.length; return x * 2; }

Tipik hatalar ve anti-paternler

  • Aşırı yükleme imzalarından sonra bir uygulama eklemeyi unutur — derleme geçmez.
  • Fonksiyon gövdesinde tip kontrolü olmadan belirli özellikler kullanılır.
  • Aşırı yüklemeleri gereksiz yere karmaşıklaştırarak okunabilir olmayan kodları oluştururlar.
  • Dönüş tiplerini açıkça tanımlamazlar veya fonksiyonun mantığı değiştiğinde imzaları güncellemeyi unutur.

Hayattan bir örnek

Olumsuz vaka

Evrensel bir imza-uygulama eklemeyi unuttular:

function sum(a: string, b: string): string; function sum(a: number, b: number): number; // uygulama yok — derleyici hata verir

Artıları:

  • Kullanışlı bir API tanımlama fikri

Eksileri:

  • Kod derlenmez, hiçbir durumu işleyemezsiniz.

Olumlu vaka

Standarta uygun bir aşırı yükleme gerçekleştirirler:

function sum(a: string, b: string): string; function sum(a: number, b: number): number; function sum(a: any, b: any): any { return typeof a === 'string' && typeof b === 'string' ? a + b : a + b; }

Artıları:

  • Tüm durumlar doğru bir şekilde işleniyor, tipler derleme aşamasında çıkarılıyor.

Eksileri:

  • Fonksiyonun gövdesi tiplerin manuel kontrolünü gerektiriyor, her durumun kontrol edilmesini unutmayın.