TypeScript Gelişmiş Konseptleri Kavramak ve Kullanmak; Tür Kavramlarına Giriş — 1

Mustafa Morbel
Cimri Engineering
Published in
5 min readOct 27, 2023

--

TypeScript

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ı;

--

--