İçeriğe geç
academia.sh

Ders 02 / 23

Temel Tipler

İlkel tipler, dizi ve salt okunur dizi gösterimleri, demetler, numaralandırmalar ve nesne tipleriyle ölçüm kaydının ilk tipli sürümü.

İçindekiler

Önceki ders tip katmanının ne yaptığını ve ne yapmadığını kurdu. Sırada bu katmanın söz dağarcığı var: ölçüm kaydının alanlarını yazabilmek için önce hangi tiplerin bulunduğunu bilmek gerekir.

TypeScript’in tip dağarcığı JavaScript’in değer modelinin üzerine oturur. Yeni değer türü eklemez; var olan türleri adlandırır ve onlardan bileşik tipler kurmanın yollarını verir. Bu ders ilkel tipleri, dizileri, demetleri ve numaralandırmaları tanıtır; sonunda ölçüm kaydının ilk tipli sürümünü yazar.

İlkel Tipler

JavaScript Temelleri kursunda tanıtılan ilkel değerlerin her birinin bir tip adı vardır. Tip adları küçük harfle yazılır:

const kimlik: string = "s-01";
const deger: number = 21.4;
const gecerli: boolean = true;
const aciklama: string | null = null;
const buyukSayac: bigint = 9007199254740993n;

console.log(typeof kimlik, typeof deger, typeof gecerli, typeof aciklama, typeof buyukSayac);
console.log(0.1 + 0.2 === 0.3);
console.log(Number.isInteger(deger), Number.isSafeInteger(9007199254740993));

Çıktı:

string number boolean object bigint
false
false false

Üç gözlem gerekir.

number tek bir sayı tipidir. Tam sayı ile gerçel sayı ayrımı yoktur; her ikisi de IEEE 754 çift duyarlıklı gösterimle tutulur. Bilgisayarlar Nasıl Çalışır kursundaki Kayan Noktalı Sayılar dersinde kurulan sınırlar burada aynen geçerlidir — ikinci satırdaki false bunun doğrudan sonucudur. Tip sistemi bu sınırı kaldırmaz, yalnızca bir sayının sayı olduğunu güvence altına alır.

typeof null değeri "object"tir. Bu, dilin taşıdığı eski bir tutarsızlıktır; tip sistemi null için ayrı bir tip tanır ama çalışma zamanı davranışını değiştirmez. Tiplerin silindiğini gösteren bir örnektir: derleyicinin gördüğü null tipiyle typeof’un gördüğü değer aynı yerden gelir ama aynı şeyi söylemez.

bigint ve symbol ayrı tiplerdir. Sayı tipinin güvenli tam sayı sınırının aşıldığı yerlerde bigint, benzersiz özellik anahtarları için symbol kullanılır. İkisi de number ile karıştırılamaz; bigint ile number doğrudan toplanamaz.

null ve undefined ayrı iki tiptir ve varsayılan katı yapılandırmada başka tiplere kendiliğinden atanamazlar. Yukarıdaki aciklama bildiriminde string | null yazılmasının nedeni budur; yalnızca string yazılsaydı derleyici atamayı reddederdi. Bu davranış strictNullChecks seçeneğine bağlıdır ve Derleyici Yapılandırması dersinde ayrıntılı ele alınacaktır.

Diziler ve Salt Okunur Diziler

Bir dizinin tipi, eleman tipinin ardına [] eklenerek yazılır. Eşdeğer bir yazım da vardır:

const degerler: number[] = [21.4, 22.1, 23.0];
const kimlikler: Array<string> = ["s-01", "s-02"];
const salt: readonly number[] = [21.4, 22.1];

console.log(degerler.length, kimlikler.length, salt.length);
salt.push(23.0);

Derleyici son satır için şu tanıyı üretir:

b2.ts(6,6): error TS2339: Property 'push' does not exist on type 'readonly number[]'.

number[] ile Array<number> aynı tiptir; ilki kısa yazımdır. readonly number[] ise farklı bir tiptir: elemanları okunabilen ama değiştirilemeyen bir dizi. Değiştirme yöntemleri (push, pop, sort, splice) bu tipte tanımlı değildir, dolayısıyla çağrıldıklarında “böyle bir özellik yok” tanısı gelir.

Buradaki readonly, Programlama Temelleri kursunda geçen değiştirilemez (immutable) kavramının tip düzeyindeki karşılığıdır — ancak yalnızca tip düzeyinde. Derlenmiş çıktıda readonly diye bir şey kalmaz; dizi çalışma zamanında sıradan bir dizidir ve tip denetiminden geçmeyen bir kod onu değiştirebilir. Gerçek değiştirilemezlik için Object.freeze gibi çalışma zamanı araçları gerekir.

Demetler

Demet (tuple), eleman sayısı ve her konumun tipi sabit olan bir dizidir. Ölçüm kaydında geçerli değer aralığını temsil etmek için uygundur:

type Aralik = [alt: number, ust: number];

const gecerliAralik: Aralik = [-40, 85];
const [alt, ust] = gecerliAralik;
console.log(alt, ust);

const yanlis: Aralik = [-40, 85, 120];

Son satır için tanı:

b3.ts(7,7): error TS2322: Type '[number, number, number]' is not assignable to type 'Aralik'.
  Source has 3 element(s) but target allows only 2.

alt: ve ust: adları demet elemanlarını belgeler; çalışma zamanında karşılıkları yoktur ve dizi yine sıra numarasıyla okunur. Adların değeri okunabilirliktedir: [number, number] tipi hangi sayının önce geldiğini söylemez, [alt: number, ust: number] söyler.

Demet ile dizinin ayrımı şudur: dizi kaç eleman olduğunu bilmez, hepsinin aynı tipte olduğunu bilir; demet kaç eleman olduğunu ve her birinin ayrı tipini bilir.

Sabit Değer Kümeleri: enum

Ölçüm kaydının birim alanı yalnızca belirli değerleri alabilir. Böyle bir kümeyi adlandırmanın bir yolu numaralandırmadır (enum):

enum Birim {
  Celsius = "C",
  Pascal = "Pa",
  Yuzde = "%",
}

const birim: Birim = Birim.Celsius;
console.log(birim, Birim.Pascal);

Bu dosya tsc --target es2022 --strict birim.ts ile derlendiğinde üretilen JavaScript:

"use strict";
var Birim;
(function (Birim) {
    Birim["Celsius"] = "C";
    Birim["Pascal"] = "Pa";
    Birim["Yuzde"] = "%";
})(Birim || (Birim = {}));
const birim = Birim.Celsius;
console.log(birim, Birim.Pascal);

Çalıştırıldığında çıktı C Pa olur.

Bu çıktı önceki dersin kuralına bir istisna gösterir: numaralandırma silinmez. Derleyici, çalışma zamanında var olan bir nesne üretir. Tip açıklamalarının aksine enum bir tip değil, hem tip hem değer üreten bir bildirimdir.

Sayısal numaralandırmada üretilen nesne daha da fazlasını yapar:

"use strict";
var Durum;
(function (Durum) {
    Durum[Durum["Gecerli"] = 0] = "Gecerli";
    Durum[Durum["Suphe"] = 1] = "Suphe";
    Durum[Durum["Hatali"] = 2] = "Hatali";
})(Durum || (Durum = {}));

Bu, Durum.Suphe için 1, Durum[1] için "Suphe" veren çift yönlü bir eşlemedir. Kolaylıktır, ama bedeli vardır: her numaralandırma paket çıktısına kod ekler ve dosya tek tek çevrildiğinde (tip bilgisi olmadan) doğru üretilemez. Bu nedenle derleyicinin, yalnızca silinebilir sözdizime izin veren bir seçeneği bulunur. Bu seçenek açıkken:

durum.ts(1,6): error TS1294: This syntax is not allowed when 'erasableSyntaxOnly' is enabled.

Seçeneğin hangi sürümden itibaren bulunduğu derleyiciye göre değişir; davranışı ise sabittir — çalışma zamanı kodu üreten tüm TypeScript sözdizimini reddeder.

Birleşim Alternatifi

Aynı kısıt, çalışma zamanında hiçbir iz bırakmayan bir yolla da ifade edilebilir:

type Birim = "C" | "Pa" | "%";

const birim: Birim = "C";
console.log(birim);

const yanlisBirim: Birim = "F";

Son satır için tanı:

b4.ts(6,7): error TS2322: Type '"F"' is not assignable to type 'Birim'.

Buradaki "C", dizgi değil bir tiptir: yalnızca "C" değerini içeren tek elemanlı küme. Böyle tiplere sabit tip (literal type) denir ve ayrı bir derste ele alınacaktır. Üç sabit tipin birleşimi, üç değerli bir küme tanımlar.

İki yaklaşımın karşılaştırması:

Ölçüt enum Sabit tip birleşimi
Çalışma zamanı kodu Üretir Üretmez
Değere erişim Birim.Celsius "C"
Dış veriyle eşleşme Dönüşüm gerekir Doğrudan
Tüm değerleri sayma Nesne üzerinden Ayrı bir dizi gerekir

Bu kurs, tip silme ilkesini bozmadığı için sabit tip birleşimini kullanacaktır.

Ölçüm Kaydının İlk Tipli Sürümü

Toplanan araçlarla modelin ilk tipli sürümü yazılabilir. Nesne tipi, alan adlarını ve tiplerini süslü ayraç içinde sayar:

type Olcum = {
  kimlik: string;
  sensor: string;
  deger: number;
  birim: "C" | "Pa" | "%";
  zaman: number;
};

const olcum: Olcum = {
  kimlik: "s-01",
  sensor: "sicaklik",
  deger: 21.4,
  birim: "C",
  zaman: 1706000000000,
};

console.log(olcum.kimlik, olcum.deger, olcum.birim);
console.log(olcum.konum);

Son satır için tanı:

b5.ts(18,19): error TS2339: Property 'konum' does not exist on type 'Olcum'.

Model artık üç şeyi bilir: hangi alanların bulunduğunu, her alanın tipini ve birim alanının değer kümesini. Bilmediği şeyler de görülüyor: sensor alanına herhangi bir dizgi yazılabilir, deger alanı için bir aralık yoktur, zaman alanının bir zaman damgası mı yoksa süre mi olduğu belli değildir. Bu boşluklar sonraki konularda kapatılacaktır.

Özet

  • İlkel tipler JavaScript’in değer modelini adlandırır; number tek bir sayı tipidir ve kayan noktalı gösterimin sınırlarını taşır.
  • T[] ile Array<T> aynı tiptir; readonly T[] değiştirme yöntemlerini içermeyen ayrı bir tiptir ve yalnızca derleme anında geçerlidir.
  • Demet, eleman sayısı ve her konumun tipi sabit olan dizidir; eleman adları belgeleme amaçlıdır.
  • enum bildirimi çalışma zamanı kodu üretir ve tip silme ilkesinin istisnasıdır; sayısal numaralandırmada çift yönlü eşleme de üretilir.
  • Sabit tiplerin birleşimi aynı kısıtı çalışma zamanında iz bırakmadan ifade eder.

Sonraki Adım

Ölçüm kaydı artık tiplidir, ancak dış dünyadan gelen veri henüz bu tipe girmemiştir. JSON.parse çağrısının döndürdüğü değerin tipi nedir, o değer nasıl güvenle modele dönüştürülür? Sonraki ders, tip sisteminin iki uç noktasını — her şeye izin veren any ile hiçbir şeye izin vermeyen unknown — ve hiçbir değeri olmayan never tipini ele alacak.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat