TypeScript, editörünüzle daha sıkı bir entegrasyon sağlamak için JavaScript'e ek sözdizimi ekler. Hataları editörünüzde erken yakalayın. TypeScript kodu, JavaScript'e dönüştürülür ve JavaScript'in çalıştığı her yerde çalışır: Bir tarayıcıda, Node.js veya Deno'da ve uygulamalarınızda. TypeScript, JavaScript'i anlar ve ek kod olmadan size harika araçlar sunmak için tür çıkarımını kullanır.

 

TypeScript Ne İçin Kullanılır?

 

Tür Güvenliği ve Hata Ayıklama

TypeScript, JavaScript'e tür güvenliği ekler. Böylece, TypeScript ile değişkenlerin ve fonksiyonların kabul ettiği veri türlerini tanımlayabiliriz. Bu, yanlış veri türlerinin kullanımını önleyerek hata ayıklamayı kolaylaştırır. Özellikle büyük projelerde bu çok faydalıdır.

 

Çalışma Zamanı - Derleme Zamanı

JavaScript, tarayıcıda veya Node.js gibi JavaScript çalışma zamanlarında doğrudan yorumlanır. Bu nedenle, JavaScript için bir derleme aşaması yoktur. Kod yazılır ve hemen çalıştırılır. TypeScript ise JavaScript'in üzerine bir katman ekler ve tür güvenliği, kod analizi ve bir derleme aşaması içerir. TypeScript dosyaları, TypeScript derleyicisi (tsc) tarafından JavaScript'e dönüştürülür ve bu dönüşüm sırasında bazı hatalar ve uyumsuzluklar tespit edilebilir. Böylece, TypeScript yazarken hataları derleme aşamasında yakalama avantajına sahibiz. JavaScript'te derleme aşamasının olmaması, TypeScript'in tür güvenliği ve hata ayıklama avantajlarını daha belirgin hale getirir.

 

Kod Okunabilirliği

TypeScript, kodumuzu daha okunabilir hale getirir. Veri türleri ve değişken adları açıkça tanımlandığı için kodun ne yaptığını anlamak daha kolaydır. Bu da kodun sürdürülebilirliğini artırır.

 

Gelişmiş Araç Desteği

TypeScript, geliştirme sürecini hızlandırmak için zengin bir araç ekosistemi sağlar. Entegre Geliştirme Ortamları (IDE'ler) ve metin editörleri TypeScript'i destekler ve kodunuzu otomatik olarak analiz edebilir, hata ayıklayabilir ve kod tamamlama önerileri sunar. Bu, daha verimli bir geliştirme deneyimi sunar.

 

Kurulum

TypeScript'i makinenize kurmak için terminalde aşağıdaki komutu çalıştırmanız yeterlidir. Tabii ki, bilgisayarınızda Node'un kurulu olması gerekir.

 

npm install -g typescript

 

Şimdi ilk TypeScript kodumuzu yazabiliriz. Öncelikle, app.ts adında bir dosya oluşturalım.

 

let age: number = 32;
console.log(age);

 

Bu kod bloğunda, age adlı bir değişken tanımladık ve ona 15 değerini atadık. age bir sayı olduğundan, türünü number olarak belirttik ve onu konsola yazdırdık. Bu, konsola 15 yazdıracak ve hiçbir hata olmayacak.

 

let age: number = 55;
age = "55"; // TypeScript error

 

Yukarıdaki kod bloğunda bir tür hatası var. Bunun nedeni, number olarak tanımlanan age değişkenine "15" string değerinin atanmasıdır.

 

TypeScript'te Kullanabileceğimiz Veri Türleri

 

Number

Tam sayılar ve ondalık değerler.

 

let age: number = 34;
let pi: number = 3.14;

console.log(age); // 34
console.log(pi);  // 3.14

 

String

Metinsel veriler için kullanılır. TypeScript, tek veya çift tırnak içinde yazılan verileri string olarak kabul eder.

 

let name: string = "Mücahit Yener";
let greeting: string = 'Merhaba, Türkiye!';

console.log(name);      // Mücahit Yener
console.log(greeting);  // Merhaba, Türkiye!

 

Boolean

İki değeri temsil eder: true ve false.

 

let isLoading: boolean = true;
let isCompleted: boolean = false;

console.log(isLoading);    // true
console.log(isCompleted); // false

 

Array

Aynı türde birden fazla değeri temsil eder. Köşeli parantezler ve bir veri türü kullanılarak tanımlanır.

 

let numbers: number[] = [44, 32, 23, 14];
let names: string[] = ["Mücahit", "Mehmet", "Uğur", "Hakan"];

console.log(numbers); // [44, 32, 23, 14]
console.log(names);   // ["Mücahit", "Mehmet", "Uğur", "Hakan"]

 

Tuple

Bir diziye benzer ancak farklı türde veriler içerebilir. Her elemanın türü belirtilir ve sabittir.

 

let user: [string, number, boolean] = ["Mücahit", 25, true];

console.log(user); // ["Mücahit", 25, true]

 

Enum

Önceden tanımlanmış değerlerle çalışmamıza olanak tanır.

 

1. Basit Enum

enum Direction {
  Up,
  Down,
  Left,
  Right
}

let move: Direction = Direction.Up;

console.log(move); // 0

 

2. Enum ile İsimlendirilmiş Sabitler

 

enum Status {
  Success = 200,
  NotFound = 404,
  ServerError = 500
}

let responseStatus: Status = Status.Success;

console.log(responseStatus); // 200

 

3. Enum Kullanarak Fonksiyon Tanımlama

 

enum Direction {
  Up,
  Down,
  Left,
  Right
}

function moveCharacter(direction: Direction) {
  switch (direction) {
    case Direction.Up:
      console.log("Character moving up");
      break;
    case Direction.Down:
      console.log("Character moving down");
      break;
    case Direction.Left:
      console.log("Character moving left");
      break;
    case Direction.Right:
      console.log("Character moving right");
      break;
  }
}

moveCharacter(Direction.Up); // Character moving up

 

4. Heterojen Enum (Karışık Değerler)

 

enum MixedEnum {
  No = 0,
  Yes = "YES"
}

let answer: MixedEnum = MixedEnum.Yes;

console.log(answer); // YES

 

5. Enum Değerini ve İsmini Erişmek

 

enum Color {
  Red,
  Green,
  Blue
}

let c: Color = Color.Green;
console.log(c);          // 1 (enum değeri)
console.log(Color[c]);   // "Green" (enum ismi)

 

6. Enum ile Birleşik Tip

 

enum Role {
  Admin,
  User,
  Guest
}

type Person = {
  name: string;
  role: Role;
}

let person1: Person = {
  name: "Alice",
  role: Role.Admin
};

console.log(person1); // { name: "Alice", role: 0 }
console.log(Role[person1.role]); // "Admin"

 

Null ve Undefined

Değeri olmayan verileri temsil eder. Bunlar, diğer tüm türlerin alt türleridir. null, değeri olmayan bir değişkeni gösterirken, undefined, henüz değer atanmamış bir değişkeni gösterir.

 

let nullValue: null = null;
let undefinedValue: undefined = undefined;

console.log(nullValue);        // null
console.log(undefinedValue);   // undefined

 

Any

TypeScript'teki tüm türlerin üst türüdür. any türündeki bir değişken herhangi bir değeri tutabilir.

 

let value: any = "Mücahit";
value = 25;
value = true;

console.log(randomValue); // true

 

Void

null ve undefined ile benzerdir. Eğer bir fonksiyon void türüne sahipse, bu fonksiyonun bir değer döndürmediği anlamına gelir.

 

function logMessage(message: string): void {
  console.log(message);
}

logMessage("This is a message."); // This is a message.

 

Never

Asla dönmeyen fonksiyonlar için kullanılır. Bir değişkene never türü atanamaz.

 

function error(message: string): never {
  throw new Error(message);
}

function infiniteLoop(): never {
  while (true) {}
}

 

TypeScript'te Arayüzler

TypeScript'te interface ve type yapıları kullanarak karmaşık türler oluşturabiliriz. Bu, projemizin kodunun okunabilirliğini ve esnekliğini sağlamaya yardımcı olur. Örneğin, bir arayüz kullanarak bir nesne türü tanımlayalım:

 

interface Product {
  name: string;
  price: number;
  stock?: boolean;
}

const product: Product = {
  name: 'Çanta',
  price: 3444
};

 

Yukarıdaki örnekte, Product adlı bir arayüz tanımladık ve name, price ve isteğe bağlı olarak stock alanlarını içeren bir nesne türü oluşturduk. Daha sonra, bu türü karşılayan bir nesneyi product değişkenine atadık.

 

Birleşim Türleri (Union Types)

Birden fazla tür kabul eden bir türdür. Türler arasına | (pipe karakteri) konularak belirtilir. Bir birleşim türüne sahip bir değişken, belirtilen türlerden herhangi birini alabilir.

 

Örneğin:

 

let value: string | number;
value = "Mücahit";
value = 34;

 

Kesişim Türleri (Intersection Types)

Birden fazla türün birleşimini temsil eder. Türler arasına & (and karakteri) konularak belirtilir. Bir kesişim türüne sahip bir değişken, bu türlerin tümünün özelliklerine sahip olabilir.

 

Örneğin:

 

interface Product {
  name: string;
  price: number;
}

type NewProduct = Product & { stock: boolean };

const newProduct: NewProduct = {
  name: 'Çanta',
  price: 3444,
  stock: false
};

 

Yukarıdaki örnekte, Product arayüzünü ve NewProduct türünü tanımladık. NewProduct türü, Product arayüzünün özelliklerini ve ek olarak { stock: boolean } türünü içerir. newProduct değişkeni, bu birleşik türe uyan bir nesneye atanmıştır ve hem Product arayüzünün hem de { stock: boolean } türünün özelliklerine sahiptir.

 

Hata Yakalama ve Hata Önleme

TypeScript, statik türler kullanarak hataları erken yakalama yeteneği sunar. Bu özellik, projelerin güvenliği ve sağlamlığı için çok önemlidir. TypeScript'in derleme sürecinde hataların yakalanması, olası çalışma zamanı hatalarını önlemeye yardımcı olur ve daha güvenli bir kod tabanı sağlar. Örneğin, bir hata yakalama ve önleme fonksiyonu yazdık. Bu fonksiyon, bir parola doğrulama hatasını önlemek zorundadır. TypeScript, bu hatayı derleme aşamasında yakalamamıza yardımcı olur.

 

function passwordValidation(password: string): void {
  if (password.length < 6) {
    throw new Error('Password must be at least 6 characters long');
  }
}

try {
  passwordValidation('123');
} catch (error) {
  console.error(error.message);
}

 

Yukarıdaki kodda, bir if koşulu kullanarak parolanın uzunluğunu kontrol eden ve eğer koşul sağlanmazsa bir Error nesnesi atan bir fonksiyon tanımladık. Daha sonra, hata yakalamak için try-catch blokları kullandık. try bloğu içinde fonksiyonu çağırarak bir parola doğrulama hatası simüle ettik. catch bloğu hatayı yakalar ve özel işlem yapar.

 

TypeScript'in hata yakalama özelliği, hataları derleme aşamasında tespit etmemize yardımcı olur. Örneğin, passwordValidation fonksiyonunda, parola alanının en az 6 karakter uzunluğunda olması gerektiğini belirttik. Eğer 6 karakterden az bir değer geçirilirse, TypeScript derleme sırasında bir hata mesajı sağlar. Bu, hataları erken yakalamamıza ve düzeltmemize olanak tanır.

 

TypeScript'i destekleyen IDE'ler de hata önlemede önemli bir rol oynar. IDE'ler, kod tamamlama ve hata bildirimleri gibi özellikler sunar.

 

Özel Hata Türü Oluşturma

customError.ts dosyasında özel hata türü oluşturmak için bir sınıf tanımlıyoruz. Potansiyel hata türleri için bir tür tanımlıyoruz ve bu sınıf, hata nesnesini genişleterek bir yığın izi eklememize olanak tanır.

 

customError.ts

export type ErrorType = 'PROJECT_LIMIT_REACHED' | 'USER_NOT_FOUND' | 'VALIDATION_ERROR';

export class CustomError extends Error {
  public type: ErrorType;

  constructor(type: ErrorType, message: string) {
    super(message);
    this.type = type;
    this.name = this.constructor.name;
    Error.captureStackTrace(this, this.constructor);
  }
}

 

Özel Hata Fırlatma

Bir özel hata fırlatma örneği.

 

hataFirlatici.ts

import { CustomError } from './customError';

function projeLimitiKontrolEt(projeSayisi: number) {
  if (projeSayisi > 5) {
    throw new CustomError('PROJECT_LIMIT_REACHED', 'Proje limiti aşıldı.');
  }
}

function kullaniciKontrolEt(kullaniciId: number) {
  const mevcutKullanicilar = [1, 2, 3];
  if (!mevcutKullanicilar.includes(kullaniciId)) {
    throw new CustomError('USER_NOT_FOUND', 'Kullanıcı bulunamadı.');
  }
}

function sifreDogrula(sifre: string) {
  if (sifre.length < 6) {
    throw new CustomError('VALIDATION_ERROR', 'Şifre en az 6 karakter olmalıdır.');
  }
}

 

Özel Hata Yakalama

Bir hata yakalandığında, hata türlerini instanceof kullanarak daraltabiliriz. Error.name daraltıldığında, IntelliSense bize yardımcı olur. Bu durumda, kullanıcıya gösterilecek hatanın PROJECT_LIMIT_REACHED olduğunu varsayabiliriz. Bu şekilde, kullanıcı için özel olarak işlenecek bir hata mesajı sağlarız.

 

hataYakalama.ts

 

import { CustomError } from './customError';
import { projeLimitiKontrolEt, kullaniciKontrolEt, sifreDogrula } from './hataFirlatici';

try {
  projeLimitiKontrolEt(10); // Proje limiti 5'i aşıyor, bu yüzden hata fırlatılacak
} catch (error) {
  if (error instanceof CustomError) {
    switch (error.type) {
      case 'PROJECT_LIMIT_REACHED':
        console.error('Hata: ', error.message); // Hata: Proje limiti aşıldı.
        break;
      case 'USER_NOT_FOUND':
        console.error('Hata: Kullanıcı bulunamadı.');
        break;
      case 'VALIDATION_ERROR':
        console.error('Hata: Doğrulama hatası.');
        break;
      default:
        console.error('Bilinmeyen hata: ', error.message);
    }
  } else {
    console.error('Bilinmeyen hata: ', error);
  }
}

try {
  kullaniciKontrolEt(10); // Kullanıcı bulunamadı, bu yüzden hata fırlatılacak
} catch (error) {
  if (error instanceof CustomError) {
    switch (error.type) {
      case 'PROJECT_LIMIT_REACHED':
        console.error('Hata: ', error.message);
        break;
      case 'USER_NOT_FOUND':
        console.error('Hata: Kullanıcı bulunamadı.');
        break;
      case 'VALIDATION_ERROR':
        console.error('Hata: Doğrulama hatası.');
        break;
      default:
        console.error('Bilinmeyen hata: ', error.message);
    }
  } else {
    console.error('Bilinmeyen hata: ', error);
  }
}

try {
  sifreDogrula('123'); // Şifre en az 6 karakter olmalıdır, bu yüzden hata fırlatılacak
} catch (error) {
  if (error instanceof CustomError) {
    switch (error.type) {
      case 'PROJECT_LIMIT_REACHED':
        console.error('Hata: ', error.message);
        break;
      case 'USER_NOT_FOUND':
        console.error('Hata: Kullanıcı bulunamadı.');
        break;
      case 'VALIDATION_ERROR':
        console.error('Hata: Doğrulama hatası.');
        break;
      default:
        console.error('Bilinmeyen hata: ', error.message);
    }
  } else {
    console.error('Bilinmeyen hata: ', error);
  }
}

 

Sonuç olarak, TypeScript kullanmak projelerimizi daha kolay yönetilebilir hale getirir. Büyük projeler veya büyük ekipler üzerinde çalışıyorsanız, TypeScript kullanmak size önemli avantajlar sağlayacaktır. Çünkü hataların ele alınması ve uygulamanın bakımının yapılması TypeScript ile çok daha mümkün hale gelir.