TS Hızlı Baslangıç
Burada TypeScript e hızlı bir başlangıç yapacagız. Aşagıdaki bilgiler bir anlamda daha kapsamlı bir dökümasyon için ilk notlar özelliğini taşıyor.
Daha sonra bu sayfa kaldırılacak ve daha kapsamlı TS notları eklenecektir.
Kisaca TS Nedir?
Section titled “Kisaca TS Nedir?”Cok kisaca buyuk projelerde JS’den yapisindan kaynaklanabilecek bazi hatalarin onune gecmeyi amaclamaktadir. En onemli ozelliligi verilerin tiplerini (types) belirterek bunlara yanlis degerler atanmasinin onune gecmek ve bu hatalari daha kodu yazarken alacagimiz TS hatalari ile onlemektir.
.ts uzantili dosya icine yazilir.
.tsx dosyalari TS ile JSX kullaniminda kullanilir.
Peki nedir bu hatalar yukarida bahsedilen ve TS bunlarin onune nasil geiciyor? Kisa ornek ile aciklayalim.
let message = "Merhaba, dünya!";message = 42; // Bu JS'de geçerli, ancak mantıksal hata potansiyeli taşırconsole.log(message); // Çıktı: 42let message: string = "Merhaba, dünya!";// message = 42; // TypeScript hata verir: 'number' tipi 'string' tipine atanamaz.console.log(message); // Çıktı: "Merhaba, dünya!"Açıklama: TypeScript’te, message değişkeninin tipi string olarak belirlendi. Yani message sadece metinleri (string) tutabilir. JavaScript’te ise tip belirlemesi olmadığı için bu tür bir hata çalışma anında ortaya çıkabilir.
Yukaridaki ornekte de goruldugu gibi syntax’i su sekilde:
let message: string = "Merhaba, dünya!";// degisken isminden sonra : (iki nokta ust uste) ve tipi yaziyoruz.Temel Tipler (Basic Types)
Section titled “Temel Tipler (Basic Types)”stringnumberbooleanarraytupleenumanyvoidnullveundefinednever
Önce en yaygın kullanılan birkaç temel tipi örneklerle görelim.
String, Number ve Boolean Tipleri
Section titled “String, Number ve Boolean Tipleri”let isim: string = "Özay";let yas: number = 30;let aktif: boolean = true;Açıklama: TypeScript’te her değişkenin türünü string, number, boolean gibi belirterek, yanlış tür atanmasını engelleyebiliriz. Mesela isim değişkeni sadece bir string alabilir; farklı bir tür verilirse hata alırız.
Any kullanimi
Section titled “Any kullanimi”Asagidaki ornekte gelen verinin string mi yoksa number mi oldugunu bilmiyoruz bu yuzden any kullandik.
let userAge : any;userAge = 25 //number kabul edildiuserAge = "45" //string kabul edildiconsole.log(userAge)Union kullanimi
Section titled “Union kullanimi”//Union kullanimi. gelen verinin tipinden emin degilsek kullanmak icin Any benzeri ancak burada tipleri seciyoruz. Asagidaki ornekte oldugu gibi veri ya string ya da number olabilir. Baska bir deger atanamaz.
let age : string | number = "25";
Literal Type kullainimi
Section titled “Literal Type kullainimi”Biraz Union kullanimina benzeriyor ancak burada type belirlemek yerine kabul edilebilecek verileri ekliyoruz. Ornegin:
let statusResult : "pending" | "approved" | "rejected";statusResult = "pending"; //kabul edildistatusResult = "rejected"; //kabul edildi//statusResult = "ozay"; kabul edilmedi, cunku bu deger onayli degerlerden degil.
console.log(statusResult)Degiskenlerde (Array) Type kullainimi
Section titled “Degiskenlerde (Array) Type kullainimi”Degiskenlerde type kullanimi yukaridaki orneklere benzer ancak atanan tipin bir array icin oldugununu belirtmek icin [] koseli parantezleri ekleniyor.
Örneklere bakalim:
let myList : string[] = ["ozay", "Mete", "Yagmur"];// alternatif kullanim, koseli parantez kullanmadan.let myList2 : Array<string> = ["ozay", "Mete", "Yagmur"];
// Union kullanimini arraylerde de kullanabiliriz.let otherList : (string | number) [] = ["ozay", "Mete", 34, 345];Type ve Interface Kullanimi
Section titled “Type ve Interface Kullanimi”Kisaca interface ve type ile kendi tiplerimizi veya tip ozel tip gruplarimizi (types) olusturup kullanabiliyoruz.
Orneklere bakalim;
// asagida User adinda ozel bir tip grubu olusturuk ve// bu grub icinde name ve age degerlerine tip atatdik.type User = { name : string, age : number}
// burada tetUser icine bir kullanici bilgisi ekledik.//name ve age icin artik User altinda tipler belirlendigi icin//tip kontrolu saglamis olduk. Ornegin age'e string eklenirse ts hatasi alacagizlet testUser : User = { name : "Ozay", age : 45,}// veya bir array icine bu tipi atayabilirizlet arrayUser : User [] = []
console.log(testUser);Interface ile ozel type olusturulmasinda simdilik sadece syntax olarak farktan basedecegim. Sonra type ve interface arasindaki farki extend kullaniminda Link detayli gorecegiz.
// type kullanimina gore tek fark tip adindan sonra = koymamak.interface User { name: string, age: number,}Optional type ?
Section titled “Optional type ?”Yukarida bahsettigimiz interface ve type kullaniminda soyle bir durum var. Eger siz ornegin User altinda name ve age degiskenlerine tip atamissaniz bunlari cagirdiginiz yerlerde sizden hem name hemde age degiskenleri istenecek. Eger bu degiskenlerden biri eksik ise ts hata verecektir.
Bunu asmak icin optional type dedigimiz bir yontem kullaniyoruz. Ornege bakalim;
type User = { name: string, age: number,}const testUser : User { name: "ozay",}// bu durumda testUser hata verecektir cunku ayrica age olmasi gerekiyor.// bu durumu asmak icin sadece degiskenden sonra soru isareti ? ekliyoruz.type User = { name: string, age?: number,}// bu durumda artik age degeri opsiyonel bir deger haline geldi.Fonksiyonlarda kullanim
Section titled “Fonksiyonlarda kullanim”TS’nin fonksiyonlarda kullanimi cok onemli bir konu. Bu konu daha detaylica islenecek. Simdilik sadece syntax kullaniminda odaklanalim.
Basit kullanim: herbir degiskenin tipini belirlemek.
function topla(a:number, b:number) { console.log(a+b)}topla(5,5) // cikti 10 olacaktopla(5,"x") //ts hata verecek cunku b'nin tipi number olarak belirlendi.Return icin tip belirleme: Bu ornekte a ve b degiskenine tip tanimlamasi yapiyoruz. Ancak ayrica bir de fonksiyonun geneline yani sonucunu (return) bir tip daha atiyoruz. Ornege bakalim;
function topla(a:number, b:number): number { return a + b;}const sonuc = topla(2,2)
console.log(sonuc) // cikti 4 olacak
//birden fazla return degeri de atamak mumkum ornegin;function topla(a:number, b:number): number | string { return a + b;}Baska bir fonksiyon ornegi, burada hem funksiyona string atadik hemde array ile donen degerlere string atadik.
function test(myArray : string[]) { myArray.forEach((value)=> console.log(value))}let myArray : string[] = ["Ali", "Veli", "Deli"]
test(myArray)Generic fonksiyon kullanimi
Section titled “Generic fonksiyon kullanimi”Cikacak degerin farkli tiplerde olmasi durumunda bunu generic fonksiyon kullanarak yapabiliyoruz.
Peki ama biz zaten Any ile bunu yapabiliyoruz neden generic kullanmamiz gerekiyor? Cunku any ile tipi kaciriyoruz, generic ile tipi yakalama sansimiz oluyor.
Asagidaki ornekte yazdiradinda bir fonksiyon olusturmak istiyoruz. Bu fonksiyon icindeki degeri console’a yazdiricak.
Ancak bu fonksiyon herhangi bir tip ile kullanilabilir. Bu durumda;
function yazdir<T>(array : T[]) :void { console.log(array)}
yazdir(["ali", "veli", "deli"]) // ["ali", "veli", "deli"]yazdir([true, false]) // [true, false]yazdir([1, 2]) // [1, 2]Yukaridaki yapiyi biraz aciklayalim;
function yazdir (array : T[]) : void burada diyorum ki sana T tipinde bir array gelecek, nasil bir sey gelecegini bilmiyorum sadece T tipinde gelecek. (Bu T disinda baska bir harf de olabilir)
void bana bir deger dondurme demek.
Simdi yazalim fonksiyonu;
function yazdir(array : T[]) :void { console.log(array)}Bunu bu sekilde yazdigimizda T ile ilgili bir hata aliyoruz. Diyor ki bana T verdin ancak ben bunun ne oldugunu bilmiyorum.
Bu sorunu asmak icin bu fonksiyonun bir “Generic” fonksiyon oldugunu belirtmemiz gerekiyor. Bunu da fonksiyon isminden hemen sonra <T> ekleyerek cozuyoruz.
Yani:
function yazdir<T>(array : T[]) :void { console.log(array)}
// <T> yerine herhangi bir harf veya kelime kullanabilriz;function yazdir<Test>(array : Test[]) :void { console.log(array)}Kullanimi daha iyi anlamak icin bir ornek daha yapalim;
interface GenericType<T> { name: string, age: number, salary: T[] // salary generic olmali cunku ne gelecegini bilmiyoruz}
const obj1 : GenericType<string> = { name: "Ali", age: 25, salary: ["1000", "2000", "3000"]}
const obj2 : GenericType<number> = { name: "Veli", age: 25, salary: [1000, 2000, 3000]}Aciklama: Yukaridaki ornekte salary belirsiz yani bize number veya string olarak gelebilir.
Bizde interface kullanarak GenericType adinda kendi type grubumuzu olusturuyouruz ve salary kismini generic olarak tanimliyoruz.
Gordugunuz gibi obj1 de string olan degerler obj2 de number oldu ve biz her iki durumda da salary icin bir type belirlemis olduk.
Extending Types
Section titled “Extending Types”Tekraralanan alanlari azaltmaya yonelik bir yapidir. Tekrarlanan ve ayni alan ve tipe sahip tipleri ayri ayri yazmak yerine yazilmis olanlardan almaya (Extend etmeye) yarar.
Asagidaki ornekte Musteri ve Kurum datalarinin tipleri belirlenmis, dikkat ederseniz ortak alanlar var yani ìd, olustrumaTarihi ve olusturanKisi alanlari ayni. Buyuk projelerde tekrarlanan bu alanlar hem kod okunurlulugunu bozar hemde kod kalitesini dusurur.
interface Musteri { id: string, olusturmaTarihi: string, olusturanKisi: string, musteriNo: string,}
interface Kurum { id: string, olusturmaTarihi: string, olusturanKisi: string, kurumNo: string,}
const musteri : Musteri = { id: "1", olusturmaTarihi: "09.06.2024", olusturanKisi: "Veli", musteriNo: "234234",}
const kurum : Kurum = { id: "14", olusturmaTarihi: "09.06.2024", olusturanKisi: "Ali", kurumNo: "234566",}Peki boyle bir durumda ne yapacagiz?
Yukaridaki ornekten yola cikalim ve ortak alanlar icin bir OrtakAlanlar interface’i olusturalim. Musteri ve Kurum interface’lerinde artik tekrar eden tipler yok.
Peki Musteri ve Kurum interface’lerine nasil OrtakAlanlar daki tipleri ekleyecegiz?
Bunun icin tip adindan sonra extends ve sonra ortak alandan alacagimiz tip adini bu ornekte OrtakAlanlar yaziyoruz.
Boylelikle Musteri icine OrtakAlanlari dahil etmis (extend etmis) oluyoruz.
interface OrtakAlanlar { id: string, olusturmaTarihi: string, olusturanKisi: string,}
interface Musteri extends OrtakAlanlar { musteriNo: string,}
interface Kurum extends OrtakAlanlar { kurumNo: string,}
const musteri : Musteri = { id: "1", olusturmaTarihi: "09.06.2024", olusturanKisi: "Veli", musteriNo: "234234",}
const kurum : Kurum = { id: "14", olusturmaTarihi: "09.06.2024", olusturanKisi: "Ali", kurumNo: "234566",}Partial, Required, ReadOnly, pick, omit kullanimi
Section titled “Partial, Required, ReadOnly, pick, omit kullanimi”Partial kullanimi;
Section titled “Partial kullanimi;”Asagidaki ornekte user1 de User tipini cagirdigimda hata aliyorum. Cunku user1 icinde sadece name kullandim ve diger tipleri cagirmadim.
Yukarida bahsetmistik boyle bir durumda tip icindeki degerin sonuna soru isareti koyarak age?: number bu deger optional yapabiliyorduk.
interface User { name: string, age: number, lastname: string, idno: number,}
const user1 : User = { name: "Veli",}Peki ama User tipindeki tum elemanlara ? isareti eklemek yerine baska bir cozum var mi? Evet Partial kullanmak;
interface User { name: string, age: number, lastname: string, idno: number,}
const user1 : User = { const user1 : Partial<User> = { name: "Veli",}Required kullanimi;
Section titled “Required kullanimi;”Required ise Partial’in tam tersini yapar. Yani soru isareti ile optional yapilmis tum tipleri zorunlu hale getirir. Asagidaki ornegi inceleyelim;
interface User { name?: string, age?: number, lastname?: string, idno?: number,}
// Required kullanarak tum User tiplerini eklemeyi zorunlu hale getiriyoruz.// Optional ozelligini kaldirmis oluyoruz.const user1 : Required<User> = { name: "Veli", age: 23, lastname: "Metin", idno: 234234,}Readonly kullanimi;
Section titled “Readonly kullanimi;”Bir veriyi sadece okunabilir hale getirir. Data tekrar degistirilemez.
interface User { name?: string, age?: number, lastname?: string, idno?: number,}
const user1 : Readonly<User> = { name: "Veli",}
// user1.name = "Ali"// artik name datasini degistirmek mumkun degil
console.log(user1.name);Pick ve Omit kullanimi;
Section titled “Pick ve Omit kullanimi;”Pick sadece belirttigimiz degiskeni almak icin kullanilir Omit ise tam tersini yapar ve belirttigimiz tipin disindakileri alir.
interface User { name: string, age: number, lastname: string, idno: number,}
// Pick sadece name aldik ve option olmamasina karsin yinede hata almadikconst user1 : Pick<User, "name"> = { name: "Veli",}interface User { name: string, age: number, lastname: string, idno: number,}
// Omit ile User'dan name disindakileri alabiliriz name artik tanimsizconst user1 : Omit<User, "name"> = { // name: "Veli", ts name adinda bir tip bulamiyor age: 23, lastname: "Veli", idno: 12312,}