TypeScript Gelişmiş Konseptleri Kavramak ve Kullanmak; Tür Kavramlarına Giriş — 1
Bugün, TypeScript ile temiz kod yazmanıza yardımcı olacak püf noktalarını inceleyeceğiz. Bu püf noktalarını öğrenerek kodlarınızı daha anlaşılır, bakımı daha kolay ve daha sağlam hale getirebilirsiniz. Ayrıca, bu püf noktalarını kullanarak hataları erken yakalayabilir ve kod yazma sürecinizi daha verimli hale getirebilirsiniz.
Tür Tanımlamaları (Type Annotations)
TypeScript, değişkenler ve fonksiyonlar için türleri tanımlamanıza olanak tanır. Tür tanımlamaları, kodunuzu daha anlaşılır hale getirebilir ve hata ayıklama sürecini kolaylaştırabilir.
Örneklere bir göz atalım:
// Bir değişkenin veri türünü açıkça belirtme
let count: number = 0;
// Bir fonksiyon parametresinin ve dönüş değerinin veri türünü açıkça belirtme
function addNumbers(a: number, b: number): number {
return a + b;
}
// Bir sınıf özelliğinin veri türünü açıkça belirtme
class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
getDetails(): string {
return `${this.name} is ${this.age} years old.`;
}
}
count
değişkeninin veri türü number
olarak belirtilmiştir. Bu, değişkenin sadece sayı değerlerini tutabileceği anlamına gelir.
addNumbers
adındaki fonksiyon iki parametre alır (a
ve b
) ve bu parametrelerin veri türleri number
olarak belirtilmiştir. Ayrıca, fonksiyonun dönüş değeri de number
olarak belirtilmiştir. Yani bu fonksiyon, iki sayıyı toplar ve sonucu bir sayı olarak döndürür
Person
adındaki sınıfın iki özelliği (name
ve age
) bulunmaktadır ve her ikisi de ilgili veri türleri ile belirtilmiştir. name
özelliği bir metin dizisi (string
) olarak belirtilmişken, age
özelliği bir sayı (number
) olarak belirtilmiştir. Sınıf içindeki getDetails
metodu da bir metin (string
) döndürmektedir.
Enums
Enumlar, belirli adlandırılmış sabitleri tanımlamanıza olanak tanır ve bu, kodunuzu daha anlaşılır hale getirebilir.
enum Color {
Red = "RED",
Green = "GREEN",
Blue = "BLUE"
}
function printColor(color: Color): void {
console.log(`The color is ${color}`);
}
printColor(Color.Red);
// Çıktı: The color is RED
Color
adındaki enum üç farklı renk değerini temsil eder: Red
, Green
, ve Blue
. Her biri string olarak belirtilmiştir. Bu tür enumlar, özellikle belirli metin değerlerini temsil etmek istediğinizde kullanışlıdır.
enumların kullanılabileceği bazı örnekler:
enum Day {
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
}
let today = Day.Wednesday;
enum GameState {
Playing,
Paused,
GameOver
}
let currentGameState = GameState.Playing;
enum HttpStatusCode {
OK = 200,
NotFound = 404,
InternalServerError = 500
}
let responseCode = HttpStatusCode.OK;
enum UserRole {
Admin,
Moderator,
User
}
let userRole = UserRole.Admin;
enum Language {
English,
Spanish,
French,
German
}
let selectedLanguage = Language.English;
enum MenuItem {
Home,
About,
Services,
Contact
}
let currentMenuItem = MenuItem.Home;
Enumlar, belirli ve sınırlı bir değer kümesini temsil etmek ve bu değerlere daha anlamlı ve okunaklı isimler vermek için kullanılır. Bu, kodun daha anlaşılır olmasını sağlar ve hata yapma olasılığını azaltır. Enumlar, özellikle sabit değerlerin kullanıldığı durumlarda oldukça kullanışlıdır.
Opsiyonel Zincirleme (Optional Chaining)
Opsiyonel zincirleme, iç içe geçmiş özelliklere ve yöntemlere güvenli bir şekilde erişmenizi sağlar ve bu, kodunuzu daha sağlam hale getirebilir. Bu özellik, nesnelerin veya alt özelliklerin null
veya undefined
olup olmadığını kontrol etmeden güvenli bir şekilde erişmenizi sağlar.
Aşağıdaki örnekte, bir Person interface’ini kullanarak opsiyonel zincirleme nasıl kullanılacağını gösteriyoruz:
interface Person {
name: string;
address?: {
street: string;
city: string;
state: string;
};
}
const person1: Person = {
name: "John",
address: {
street: "123 Main St",
city: "Anytown",
state: "CA",
},
};
const person2: Person = {
name: "Jane",
};
console.log(person1?.address?.city); // Çıktı: Anytown
console.log(person2?.address?.city); // Çıktı: undefined
Person
adlı bir interface name
adında bir zorunlu özellik ve address
adında bir isteğe bağlı (opsiyonel) özellik içerir. address
özelliği, içinde street
, city
, ve state
adlı alt özellikleri içeren bir nesneye sahiptir.
person1
nesnesinin address
özelliği mevcut olduğu için, person1?.address?.city
ifadesi Anytown
değerini döndürür.
person2
nesnesinin address
özelliği tanımlanmamıştır (isteğe bağlı), bu nedenle person2?.address?.city
ifadesi undefined
döndürür. Hata oluşmaz, çünkü opsiyonel zincirleme, herhangi bir nesne veya özelliğin varlığını kontrol eder ve eğer özellik veya nesne yoksa hata vermeksizin undefined
döner.
Nullish Birleştirme (Nullish Coalescing)
Nullish birleştirme operatörü (??
), bir değişken veya ifade null
veya undefined
ise varsayılan bir değer sağlamanıza yardımcı olur. Bu, yanıltıcı değerlere dayanmadan varsayılan bir değeri belirtmenizi sağlar.
Aşağıdaki örnekte, nullish birleştirmeyi nasıl kullanacağınızı gösteriyoruz:
let value1: string | null = "John";
let value2: string | undefined = undefined;
let value3: string | null | undefined = null;
console.log(value1 ?? "default value"); // Çıktı: "John"
console.log(value2 ?? "default value"); // Çıktı: "default value"
console.log(value3 ?? "default value"); // Çıktı: "default value"
value1
değişkeni null
değil, "John" değeriyle dolu olduğu için Nullish Birleşim operatörü, value1
'i kullanır ve "John" değerini döndürür.
value2
değişkeni undefined
olduğu için Nullish Birleşim operatörü, value2
'yi kullanmaz ve varsayılan değer olan "default value" değerini döndürür.
value3
değişkeni hem null
hem de undefined
değerlerini içermez, bu nedenle Nullish Birleşim operatörü yine varsayılan değer olan "default value" değerini döndürür.
Nullish Birleşim operatörü, özellikle bir değişkenin null
veya undefined
olup olmadığını kontrol etmek ve bu durumlarda varsayılan bir değer atamak için kullanılır. Bu operatör, sadece null
veya undefined
olduğunda varsayılan değeri kullanır, diğer “falsy” değerler (örneğin, boş bir dizi veya 0 gibi) durumunda varsayılan değeri kullanmaz.
Generic Fonksiyonlar
Generics, TypeScript’in güçlü bir özelliğidir ve farklı türlerle çalışabilen yeniden kullanılabilir kod yazmanıza yardımcı olabilir. Bu, kod tekrarını azaltabilir ve kodunuzu daha bakımı kolay hale getirebilir.
İşte bir generic kullanımı örneği:
function combine<T, U>(input1: T, input2: U): [T, U] {
return [input1, input2];
}
let combined1 = combine<string, number>("hello", 42);
console.log(combined1); // Çıktı: ["hello", 42]
let combined2 = combine<number, boolean>(100, true);
console.log(combined2); // Çıktı: [100, true]
Bu genel fonksiyon, iki farklı türde argüman alır (T ve U), ve bu argümanları bir dizi içinde birleştirip döndürür.
combine
fonksiyonunu kullanarak farklı türdeki değerleri birleştirdik. İlk çağrıda bir dize ve bir sayı birleştirildi, ikinci çağrıda bir sayı ve bir boolean birleştirildi. Fonksiyon, bu farklı türdeki değerleri bir dizi içinde döndürdü.
Generic fonksiyonlar, farklı türlerdeki verilerle çalışmak istediğinizde çok kullanışlıdır. TypeScript’de bu tür fonksiyonlar, kodunuzu daha esnek hale getirmenize ve tip güvenliğini korumanıza yardımcı olur.
Arabirimler (interfaces)
Arabirimler, kodunuzu daha okunabilir hale getirmenize yardımcı olabilir. Bir sınıfın, nesnenin veya işlemin nasıl görünmesi gerektiğini tanımlayan bir sözleşme olarak hizmet edebilirler. Ayrıca, ortak bir dil oluşturmanıza ve hataları önlemenize yardımcı olabilirler.
// Bir kişiyi temsil eden arayüz (interface)
interface Person {
firstName: string;
lastName: string;
age?: number; // Yaş isteğe bağlıdır, yani belirtilmeyebilir.
}
// Kişiye "Merhaba" diyen fonksiyon
function sayHello(person: Person): void {
console.log(`Merhaba, ${person.firstName} ${person.lastName}!`);
if (person.age) {
console.log(`Siz ${person.age} yaşındasınız.`);
}
}
let person1 = { firstName: "John", lastName: "Doe", age: 30 };
let person2 = { firstName: "Jane", lastName: "Doe" };
// Fonksiyonu kullanarak kişilere selam veriyoruz
sayHello(person1); // Çıktı: "Merhaba, John Doe! Siz 30 yaşındasınız."
sayHello(person2); // Çıktı: "Merhaba, Jane Doe!"
Bu kod, bir kişinin adını, soyadını ve yaşını temsil etmek için bir Person
arayüzü oluşturur. age
özelliği isteğe bağlıdır, yani bazı kişilerin yaşını belirtmeyebiliriz.
Ardından, sayHello
adlı bir fonksiyon tanımlarız. Bu fonksiyon, bir kişi nesnesini kabul eder ve bu kişinin adını ve soyadını kullanarak ona "Merhaba" der. Eğer kişinin yaş bilgisi varsa, yaşını da söyler.
Son olarak, iki kişi örneği (person1
ve person2
) oluştururuz ve sayHello
fonksiyonunu kullanarak bu kişilere selam veririz. Eğer kişinin yaş bilgisi yoksa, yaş hakkında bir şey söylemeyiz.
Bu yazıda, TypeScript’in temel ve gelişmiş konseptlerini inceledik ve kod yazarken kullanabileceğimiz önemli teknikleri öğrendik. TypeScript’i kullanarak kodlarınızı daha anlaşılır, güvenilir ve bakımı daha kolay hale getirebilirsiniz. Ayrıca, hataları erken yakalama ve kod yazma sürecinizi daha verimli hale getirme konularına da değindik.
Serinin devamı;