Yasin Ateş
5 dk Medium

A’dan Z’ye Typescript

A’dan Z’ye Typescript

TypeScript Nedir?

TypeScript, Microsoft tarafından geliştirilen açık kaynak bir programlama dilidir. JavaScript diline katı kurallar eklemeyi sağlar.

TypeScript Özellikleri

TypeScript = JavaScript’tir: TypeScript temel yapı taşlarını JavaScript’ten alır. Bu nedenle TypeScript’i öğrenmeden önce JavaScript yetkinliğinizin olması gerekir. TypeScript ile yaptığınız bütün geliştirmeleriniz, makalenin kurulum adımında da göreceğiniz üzere JavaScript’e dönüştürülür.

TypeScript, tüm JavaScript kütüphanelerini destekler: TypeScript ile derlenen JavaScript çıktısı, bütün javascript kütüphaneleri ile birlikte kullanılabilir.

TypeScript, taşınabilir ve portatiftir: TypeScript platform-serbest bir dildir ve farklı tarayıcılarda, cihazlarda, işletim sistemlerinde çalışabilir. javaScript’in çalıştığı herhangi bir ortamda çalışabilir. Hali hazırda javaScript ile geliştirilme yapılan bir projeye entegre edilebilir.

TypeScript Avantajları

★ TypeScript, nesne yönelimlidir.

★ TypeScript, statik veri tiplemesine sahiptir.

★ TypeScript, ES6 özelliklerini içeririnde barındırır.

★ TypeScript, modülerdir.

★ TypeScript’in söz dizimi Java, C# gibi yüksek seviyeli dillere benzerdir.

TypeScript kodları, tarayıcılar tarafından direkt olarak yorumlanamayacağı için kodların derlenmesi ve JavaScript çıktısının oluşturulması gerekiyor.

Eğer hemen TypeScript yazmaya başlamak isterseniz, makalenin kurulum adımını geçerek, Codepen’i veya TypeScript’in kendi dokümantasyon sayfasındaki Playground’ı kullanabilirsiniz.

TypeScript Kurulumu

TypeScript’i kurabilmek için ilk başta bilgisayarımızda Node Js’in kurulu olması gerekiyor. Ardından terminal üzerinden,

1npm install -g typescript

komutunu çalıştıralım.

Şimdi örnek olarak, terminal üzerinden TypeScript yazmak istediğimiz dizine ilerleyerek, dizinimizde bir main.ts oluşturalım ve içerisine,

1const num:number = 12 
2console.log(num)

bu kodları yazalım.

Ardından,

1tsc main.ts -w

komutunu terminalde çalıştıralım.

Bu komut ile ana dizinimde bulunan main.ts dosyası JavaScript’e dönüştürülerek, ana dizine çıktılandı ve ana dizindeki main.js dosyasının içeriği,

1var num = 12; 
2console.log(num);

bu şekilde oldu.

-w parametresi main.ts dosyasıdaki değişikliklerin anlık olarak izleneceği ve dosya içerisindeki kodların anlık olarak main.js dosyasına çıktılanacağı anlamına gelir. Zorunlu bir parametre değildir.

Bu sayede ilk TypeScript kodumuzu yazmış ve derlemiş olduk. 🙂

Yapılandırma (Configuration) ve Klasör Yapısı

Terminalde,

1tsc --init

komutunu çalıştırdıktan sonra. dizinimizde tsconfig.json dosyası oluşacaktır. Dizinizimde oluşan config dosyasındaki parametreleri düzenleyerek örnek bir klasör yapısı oluşturalım.

1{
2    "compilerOptions": {
3        "outDir": "./dist/",
4        "sourceMap": true,
5        "module": "commonjs",
6        "target": "es6",
7    },
8    "include": ["src"],
9    "exclude": ["node_modules", "build", "dist","__test__"]
10}

Bu yapılandırma dosyasına göre, src dizini içerisinde yer alan .ts dosyalarımız dist dizinine çıktılanacaktır.

Statik Veri Tiplemesi (Static Type Checking) Nedir?

TypeScript ile değişkenler, fonksiyonlar, ve fonksiyon parametreleri için tip kontrolü (type checking) yapabilirsiniz.

Özellikleri

★ Tamamen isteğe bağlıdır.

★ Hataları bulmanıza ve önlemenize yardımcı olur.

★ Daha açıklayıcı ve okunaklı kod yazmanızı sağlar.

Tipler

String: Metinsel veri türleri için kullanılır.

1let color: string = "blue";
2color = 'red';

Number: Sayısal veri türleri için kullanılır. ES6 ile gelen ikili ve sekizli değerleri de destekler.

1let decimal: number = 6;
2let float: number = 6.5;
3let hex: number = 0xf00d;
4let binary: number = 0b1010;
5let octal: number = 0o744;

Boolean: true/false değerler için kullanılır.

1let isLoading: boolean = true;
2let isDone: boolean = false;

Array: Dizi tanımlamaları için kullanılır. İki farklı yazım şekli vardır.

1// 1. Yöntem
2let list: number[] = [1, 2, 3];
3
4// 2. Yöntem
5let list: Array<number> = [1, 2, 3];

Any: Bilinmeyen değişken tipleri için kullanılır. Örneğin, dinamik değerler içeren değişkenler için kullanılabilir.

1let notSure: any = 4;
2notSure = "Değer string olarak değişti :)";
3notSure = false;

Void: Geriye herhangi bir değer return etmeyen fonksiyonlarda ve null veya undefined değer içeren değişkenlerde kullanılır.

1// Fonksiyonlarda kullanımı
2function warnUser(): void {
3 console.log("Bu fonksiyon geriye herhangi bir değer return edemez...");
4}
5
6// Değişkenlerde kullanımı
7let unusable: void = undefined;
8unusable = null;

Null: null değer içeren değişkenlerde kullanılır.

1let users: null = null;

Undefined: undefined değer içeren değişkenlerde kullanılır.

1let users: undefined = undefined;

Tuple: Grup türleri bilinen ancak aynı olması gerekmeyen dizilerde kullanılır.

1let x: [string, number];
2x = ["merhaba", 10]; // Başarılı
3
4x = [10, "merhaba"]; // Başarısız

Enum: Obje içerisindeki key’lere veya key değerlerine daha kolay erişmek için kullanılır.

1enum Color { Red, Green, Blue }
2let c: Color = Color.Green;

Key değerleri, varsayılan olarak 0'dan başlar ancak bunu değiştirmek mümkündür.

Tek bir key’in değerini veya birden fazla key’in değerini değiştirebiliriz. 👌💪

1enum Color {Red = 1, Green, Blue}
2let c: Color = Color.Green;
3
4// veya
5
6enum Color {Red = 1, Green = 2, Blue = 4}
7let c: Color = Color.Green;

Key’lere erişmek için indis numarasını yazmamız yeterli. 😋

1enum Color {Red = 1, Green, Blue}
2let colorName: string = Color[2];
3
4console.log(colorName) // "Green"

Takma Adlar (Type Alias)

type sözcüğü ile tanımlanan ifadeler, tipleri içerisinde tutar ve bu tipleri birden fazla yerde kullanmamıza olanak tanır. 👌

1type user = string | object
2
3let user: user = { name: 'Melis', age: 22 }
4let userTwo: user = 'Melis'

Yukarıdaki örnekte yer alan user alias’ı hem string tipindeki değişkenleri hem de object tipindeki değişkenler için tip kontrolünü sağlar.

Fonskiyonlar

Void: Geriye herhangi bir değer return etmeyen fonksiyonlarda kullanılır.

1const user = (name: string, age: number): void => {
2  console.log(`İsminiz: ${name} ve yaşınız: ${age}`);
3};

Geriye Değer Döndürebilen Fonksiyonlar:

1let logDetails = (user: { name: string; age: number }): string => {
2  return `İsminiz: ${user.name} ve Yaşınız: ${user.age}`;
3};

Yukarıdaki örnek, object tipinde parametre alan ve geriye string tipinde değer döndüren bir fonksiyon kullanım örneğidir.

Parametresi Zorunlu (Required) Olmayan Fonksiyonlar:

1let logDetails = (user: { name: string; age?: number }, action?): string => {
2  if (action === 'add') {
3    return 'Kullanıcı eklendi';
4  }
5  return `İsminiz: ${user.name} ve Yaşınız: ${user.age}`;
6};
7
8const userString = logDetails({ name: 'Melis' }, 'add');
9console.log(userString);

Yukarıdaki örnekte, action parametresi ve user objesi içinde gönderilen age anahtar kelimesi, zorunlu bir parametre değildir. Fonksiyon çalıştırıldığında bu parametreler gönderilmemiş durumsaysa bu kısım işleme alınmaz.

Sınıf Tabanlı Objeler (Class Based Object)

Sınıflar (Classes)

1class User {
2  name: string;
3  age: number;
4
5  constructor(a: string, b: number) {
6    this.name = a;
7    this.age = b;
8  }
9
10  get() {
11    return `İsminiz: ${this.name} ve Yaşınız: ${this.age}`;
12  }
13}
14
15const user = new User('Melis', 22);
16
17user.name = 'Yasin';
18user.age = 21;

Yukarıdaki örnektede gördüğümüz üzere, sınıf içerisinde yapılan değişken tipi tanımlamaları ve method içerisine gönderilen parametrelerin tip tanımlamaları, değişkenler ve fonksiyonlardaki ile aynıdır.

Soyut Sınıflar (Abstract Classes)

Soyut sınıflar,

★ Kendi instance objesinden türeyemeyen sınıflardır.

★ Kendisini kullanan başka sınıfların instance’ları aracılığıyla içerisindeki özelliklere erişilmesini sağlayan sınıflardır.

1abstract class User {
2  name: string;
3  age: number;
4
5  constructor(a: string, b: number) {
6    this.name = a;
7    this.age = b;
8  }
9
10  get() {
11    return `İsminiz: ${this.name} ve Yaşınız: ${this.age}`;
12  }
13}
14
15const user = new User('Melis', 22); // Error: Cannot create an instance of an abstract class.

Eğer soyut bir sınıftan instance üretmeye çalışırsak, hata alırız.

1abstract class User {
2  name: string;
3  age: number;
4
5  constructor(a: string, b: number) {
6    this.name = a;
7    this.age = b;
8  }
9
10  get() {
11    return `İsminiz: ${this.name} ve Yaşınız: ${this.age}`;
12  }
13}
14
15class Person extends User {
16  constructor(a,b) {
17    super(a,b);
18  }
19
20  sayHello() {
21    return `Merhaba ${this.name}`
22  }
23}
24
25const person = new Person('Melis', 22);
26
27console.log(person.get());
28console.log(person.sayHello());

Yukarıdaki örnekte, Person sınıfı instance’ından türetilen obje ile hem Person sınıfı içindeki parametrelere hem de User sınıfı içindeki parametrelere erişilebilir.

Interface

Dışarıdan erişilebilir durumda olan elemanları, objelere veya sınıflara bildiren yapılardır.

★ Birbirlerinden extend olabilirler.

★ Birbirlerinden implement olamazlar.

★ Objelere ve sınıflara atanabilirler.

Objelerde Kullanımı

1interface IsPerson {
2  name: string;
3  age?: number;
4  speak(a: string): void;
5}
6
7const user: IsPerson = {
8  name: 'Melis',
9  // age: 22,
10  speak(text: string): void {
11    console.log(text);
12  },
13};
14
15console.log(user);
16user.speak('Merhaba!');

Yukarıdaki örnekte, age değeri obje içerisinde kullanımı zorunlu bir parametre olmadığı için soru işareti (?) ile birlikte kullanılmıştır.

Sınıflarda Kullanımı

1interface IsPerson {
2  name: string;
3  age?: number;
4  speak(a: string): void;
5}
6
7// implements ifadesi ile kullanılır
8class User implements IsPerson {
9  name: string = 'Melis';
10  age: number = 22;
11
12  speak(): string {
13    return `Merhaba ben ${this.name} ve yaşım ${this.age}`;
14  }
15}
16
17const user = new User();
18
19console.log(user.speak());

Yukarıdaki örnekte, User sınıfı, IsPerson Interface’i içinde tanımlanmış olan özellikleri kullanmaktadır.

“public”, “private” ve “readonly”

public: Sınıf içerisinde kullanılan özellikleri dışarıdan erişilebilir ve değiştirilebilir hale getirir.

private: Sınıf içerisinde kullanılan özelliklerin dışarıdan erişilebilme ve değiştirilebilme durumunu devre dışı bırakır.

readonly: Sınıf veya Interface içerisinde kullanılan özelliklerin dışarıdan değiştirilebilme durumunu devre dışı bırakır.

Interface’lerde Kullanımı

1interface IsPerson {
2  readonly name: string;
3}
4
5const user: IsPerson = {
6  name: 'Melis'
7};
8
9user.name = 'Yasin'; // Error: Cannot assign to 'name' because it is a read-only property

Sınıflarda Kullanımı

1class User {
2  readonly name: string;
3}
4
5const user = new User();
6user.name = 'Yasin'; // Error: Cannot assign to 'name' because it is a read-only property

Sınıf veya obje içerisindeki readonly değerleri değiştirmeye çalışırsak, hata alırız.

Sonuç

JavaScript diline katı kurallar eklememize yardımcı olan TypeScript, ilk başlarda göze biraz tuhaf gözükse de alıştıktan sonra geliştirme esnasında karşımıza çıkardığı hata mesajlarıyla hayatımızı kolaylaştırıyor.

Bu makalede kullandığım resimlere ve paylaşmış olduğum kaynak kodlara, makale içerisinde bırakmış olduğum resimlerin altındaki linkler üzerinden ulaşabilirsiniz.

Makaleyi hazırlarken kullandığım kaynaklar;

TypeScript Documentation: https://typescriptlang.org

The Net Ninja: https://www.youtube.com/watch?v=2pZmKW9-I_k&list=PL4cUxeGkcC9gUgr39Q_yD6v-bSyMwKPUI

Traversy Media: https://www.youtube.com/watch?v=rAy_3SIqT-E