İçeriğe geç
TypeScript

TypeScript 5.x Yenilikleri: Kapsamlı İnceleme

Tarık Tunç
TypeScript 5.x Yenilikleri: Kapsamlı İnceleme

TypeScript 5.x Yenilikleri: Kapsamlı İnceleme

TypeScript 5 serisi, performans iyileştirmeleri, yeni tip özellikleri ve geliştirici deneyimini artıran birçok yenilik getirdi. Decorator'lerin standartlaşması, const type parametreleri, modül çözümleme geliştirmeleri ve daha fazlası ile TypeScript daha güçlü ve kullanışlı hale geldi. Bu yazıda TypeScript 5.0'dan 5.7'ye kadar olan tüm önemli yenilikleri inceleyeceğiz.

TypeScript 5.0: Decorator'ler (Stage 3)

TC39 Stage 3 standartlarına uygun yeni decorator sözdizimi:

// Yeni standart decorator
function logged(
  target: Function,
  context: ClassMethodDecoratorContext
) {
  const methodName = String(context.name);

  function replacementMethod(this: any, ...args: any[]) {
    console.log(`${methodName} çağrıldı:`, args);
    const result = target.call(this, ...args);
    console.log(`${methodName} sonuç:`, result);
    return result;
  }

  return replacementMethod;
}

function sealed(target: Function, context: ClassDecoratorContext) {
  Object.seal(target);
  Object.seal(target.prototype);
}

@sealed
class UserService {
  @logged
  getUser(id: string) {
    return { id, name: 'Test User' };
  }

  @logged
  deleteUser(id: string) {
    return true;
  }
}

Auto-Accessor

class Person {
  // auto-accessor: otomatik getter/setter oluşturur
  accessor name: string;
  accessor age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}

// Decorator ile birlikte kullanım
function clamp(min: number, max: number) {
  return function (
    target: ClassAccessorDecoratorTarget<any, number>,
    context: ClassAccessorDecoratorContext
  ) {
    return {
      set(value: number) {
        target.set.call(this, Math.min(max, Math.max(min, value)));
      },
      get() {
        return target.get.call(this);
      },
    };
  };
}

class Config {
  @clamp(0, 100)
  accessor volume: number = 50;
}

TypeScript 5.0: Const Type Parameters

// const type parameter: Literal tip çıkarımı zorlar
function createRoute<const T extends readonly string[]>(paths: T) {
  return paths;
}

// const olmadan: string[]
const routes1 = createRoute(['home', 'about', 'contact']);
// const ile: readonly ["home", "about", "contact"]
const routes2 = createRoute(['home', 'about', 'contact']);

// Pratik kullanım: Config builder
function defineConfig<const T extends Record<string, unknown>>(config: T): T {
  return config;
}

const config = defineConfig({
  theme: 'dark',
  lang: 'tr',
  features: ['auth', 'i18n'] as const,
});
// typeof config.theme = "dark" (string değil)
Bilgi: const type parameter, as const assertion'ı fonksiyon çağrısı tarafına taşır. Bu sayede çağıran taraf as const yazmak zorunda kalmaz.

TypeScript 5.1-5.2 Yenilikleri

Unrelated Types for Return (5.1)

// 5.1: undefined döndüren fonksiyonlar explicit return gerektirmez
function logMessage(msg: string): undefined {
  console.log(msg);
  // return undefined; artık gerekli değil
}

// Getter/setter farklı tipler
class Box {
  #value: number = 0;

  // setter number alır
  set value(val: number) {
    this.#value = val;
  }

  // getter string döner
  get value(): string {
    return `Değer: ${this.#value}`;
  }
}

Using Declarations (5.2)

// Explicit Resource Management (using keyword)
class DatabaseConnection implements Disposable {
  constructor(private url: string) {
    console.log('Bağlantı açıldı:', url);
  }

  query(sql: string) {
    return []; // query sonuçları
  }

  [Symbol.dispose]() {
    console.log('Bağlantı kapatıldı:', this.url);
  }
}

// using ile otomatik cleanup
async function fetchData() {
  using connection = new DatabaseConnection('postgres://localhost');
  const results = connection.query('SELECT * FROM users');
  return results;
  // Fonksiyon bittiğinde connection otomatik dispose edilir
}

// Async dispose
class FileHandle implements AsyncDisposable {
  async [Symbol.asyncDispose]() {
    await this.close();
  }

  async close() {
    console.log('Dosya kapatıldı');
  }
}

async function processFile() {
  await using file = new FileHandle();
  // ... dosya işlemleri
  // Otomatik await file[Symbol.asyncDispose]()
}

TypeScript 5.3-5.4 Yenilikleri

Import Attributes (5.3)

// Import assertions yerine import attributes
import data from './config.json' with { type: 'json' };
import styles from './styles.css' with { type: 'css' };

// Dynamic import ile
const config = await import('./config.json', {
  with: { type: 'json' }
});

NoInfer Utility Type (5.4)

// NoInfer: Belirli pozisyondan tip çıkarımını engeller
function createFSM<S extends string>(config: {
  initial: NoInfer<S>;
  states: S[];
}) {
  return config;
}

// Hata: 'idle' states dizisinde olmalı
createFSM({
  initial: 'idle',       // NoInfer sayesinde buradan çıkarım yapılmaz
  states: ['active', 'inactive'], // Tip S buradan çıkarılır
});

// Doğru kullanım
createFSM({
  initial: 'active',
  states: ['active', 'inactive'],
});

TypeScript 5.5-5.7 Yenilikleri

Inferred Type Predicates (5.5)

// TypeScript 5.5: Otomatik type predicate çıkarımı
const numbers = [1, null, 2, undefined, 3].filter(
  (x) => x !== null && x !== undefined
);
// TypeScript 5.5: number[] (önceden (number | null | undefined)[] olurdu)

// Otomatik çıkarım
function isString(value: unknown) {
  return typeof value === 'string';
}
// TypeScript 5.5 bunu otomatik olarak type predicate olarak algılar
// function isString(value: unknown): value is string

Regular Expression Checking (5.5)

// TypeScript 5.5: Regex syntax kontrolü
const regex1 = /hello world/;        // OK
const regex2 = /[a-z]+/gi;           // OK
// const regex3 = /[a-z/;             // Hata: Unterminated regex
// const regex4 = /(?<name>[a-z+)/;  // Hata: Invalid regex

Isolated Declarations (5.5)

// tsconfig.json
{
  "compilerOptions": {
    "isolatedDeclarations": true
  }
}

// Fonksiyon dönüş tipleri açıkça belirtilmeli
export function add(a: number, b: number): number {
  return a + b;
}

// Hata: isolatedDeclarations modunda dönüş tipi gerekli
// export function multiply(a: number, b: number) {
//   return a * b;
// }
İpucu: isolatedDeclarations, paralel tip oluşturmayı mümkün kılarak büyük projelerde derleme süresini önemli ölçüde kısaltabilir. SWC ve oxc gibi araçlar bu özellikten faydalanır.

Config Extends Glob Patterns (5.5+)

// tsconfig.json
{
  "extends": ["@repo/config-typescript/base", "./tsconfig.paths.json"],
  // Birden fazla config dosyasını extend edebilirsiniz
}
Uyarı: TypeScript 5.x serisinin bazı özellikleri (using declarations, import attributes) henüz tüm runtime'larda desteklenmeyebilir. Polyfill veya target ayarlarınızı kontrol edin.

Migration ve Güncelleme

# TypeScript güncelleme
npm install typescript@latest

# Breaking change kontrolü
npx tsc --noEmit

# Versiyon bazlı yenilik kontrolü
npx tsc --version

Sonuç

TypeScript 5.x serisi, standart decorator'ler, const type parametreleri, using declarations, NoInfer ve otomatik type predicate çıkarımı gibi güçlü özelliklerle dilin ifade gücünü artırdı. Her yeni sürüm hem geliştirici deneyimini hem de derleme performansını iyileştiriyor. Projelerinizi güncel tutarak bu özelliklerden faydalanın.

Kaynaklar

İlgili Yazılar