İçeriğe geç
TypeScript

TypeScript Declaration Files (.d.ts) Rehberi

Tarık Tunç
TypeScript Declaration Files (.d.ts) Rehberi

TypeScript Declaration Files (.d.ts) Rehberi

Declaration file'lar (.d.ts), JavaScript kütüphaneleri ve modülleri için tip bilgisi sağlayan özel TypeScript dosyalarıdır. Mevcut JavaScript kodunuza tip güvenliği eklemeden, TypeScript'in bu kodla güvenle çalışmasını sağlar. Bu yazıda declaration file'ların oluşturulmasını, kullanımını ve best practice'leri inceleyeceğiz.

Declaration File Nedir?

Declaration file'lar, JavaScript kodunun tip bilgisini içeren dosyalardır. Çalışma zamanında hiçbir etkisi yoktur, yalnızca geliştirme zamanında tip kontrolü için kullanılır:

// matematik.js - JavaScript kütüphanesi
function topla(a, b) {
  return a + b;
}

function cikar(a, b) {
  return a - b;
}

module.exports = { topla, cikar };

// matematik.d.ts - Declaration file
declare function topla(a: number, b: number): number;
declare function cikar(a: number, b: number): number;

export { topla, cikar };

// Kullanım - artık tip güvenli!
import { topla, cikar } from "./matematik";
topla(5, 3);      // Geçerli
// topla("5", 3);  // HATA: string number'a atanamaz

Declaration File Oluşturma Yöntemleri

1. Otomatik Oluşturma

// tsconfig.json
{
  "compilerOptions": {
    "declaration": true,      // .d.ts dosyalarını oluştur
    "declarationDir": "./types", // Çıktı dizini
    "declarationMap": true,   // .d.ts.map dosyaları (debug)
    "emitDeclarationOnly": true // Sadece .d.ts oluştur
  }
}

// Kaynak dosya: src/utils.ts
export function formatTarih(tarih: Date): string {
  return tarih.toLocaleDateString("tr-TR");
}

export interface Kullanici {
  id: number;
  isim: string;
}

// Otomatik oluşturulan: types/utils.d.ts
export declare function formatTarih(tarih: Date): string;
export interface Kullanici {
  id: number;
  isim: string;
}

2. Manuel Oluşturma

// global.d.ts - Global tip tanımları
declare global {
  interface Window {
    analytics: {
      track(event: string, properties?: Record<string, any>): void;
      identify(userId: string): void;
    };
    __APP_CONFIG__: {
      apiUrl: string;
      version: string;
      debug: boolean;
    };
  }

  // Global fonksiyon
  function logger(message: string, level?: "info" | "warn" | "error"): void;

  // Global değişken
  var APP_VERSION: string;
}

export {}; // Bu dosyayı modül yapmak için gerekli

// custom-module.d.ts - Modül tipi tanımlama
declare module "untyped-library" {
  export function doSomething(input: string): number;
  export function doSomethingElse(config: Config): Promise<Result>;

  export interface Config {
    apiKey: string;
    timeout?: number;
  }

  export interface Result {
    success: boolean;
    data: unknown;
  }

  export default class Client {
    constructor(config: Config);
    connect(): Promise<void>;
    disconnect(): void;
  }
}
İpucu: Kendi TypeScript projenizde declaration: true kullanarak otomatik .d.ts dosyaları oluşturun. Manuel declaration file yazmak genellikle sadece tiplendirilmemiş JavaScript kütüphaneleri için gereklidir.

DefinitelyTyped ve @types

# Kütüphane tip paketlerini yükleme
npm install --save-dev @types/node
npm install --save-dev @types/express
npm install --save-dev @types/lodash
npm install --save-dev @types/react

# Tip paketi var mı kontrol etme
npm search @types/kutuphane-adi

# tsconfig.json'da typeRoots
{
  "compilerOptions": {
    "typeRoots": [
      "./node_modules/@types",
      "./src/types"     // Özel tip dizini
    ],
    "types": [
      "node",
      "jest"  // Sadece belirtilen tipleri dahil et
    ]
  }
}

Module Augmentation

// Mevcut modülü genişletme
// express-augmentation.d.ts
import "express";

declare module "express" {
  interface Request {
    kullanici?: {
      id: number;
      isim: string;
      rol: "admin" | "kullanici";
    };
    requestId: string;
  }
}

// Kullanım
import express from "express";
const app = express();

app.use((req, res, next) => {
  req.kullanici = { id: 1, isim: "Tarik", rol: "admin" };
  req.requestId = crypto.randomUUID();
  next();
});

// process.env genişletme
// env.d.ts
declare namespace NodeJS {
  interface ProcessEnv {
    NODE_ENV: "development" | "production" | "test";
    PORT: string;
    DATABASE_URL: string;
    JWT_SECRET: string;
    API_KEY?: string;
  }
}

// Artık process.env tip güvenli
const port = parseInt(process.env.PORT); // string
const dbUrl = process.env.DATABASE_URL;  // string
Uyarı: Module augmentation yaparken dikkatli olun. Yanlış tip genişletmeleri, gerçek API ile uyumsuz tipler oluşturabilir. Özellikle process.env genişletmelerinde, tanımlanan ortam değişkenlerinin gerçekten mevcut olduğundan emin olun.

Wildcard Module Declarations

// assets.d.ts - Asset dosyaları için tip tanımları
declare module "*.css" {
  const content: Record<string, string>;
  export default content;
}

declare module "*.scss" {
  const content: Record<string, string>;
  export default content;
}

declare module "*.svg" {
  const content: string;
  export default content;
}

declare module "*.png" {
  const content: string;
  export default content;
}

declare module "*.json" {
  const value: any;
  export default value;
}

// Artık asset import'ları tip güvenli
import styles from "./App.module.css";
import logo from "./logo.svg";
import data from "./config.json";
Bilgi: Vite ve Next.js gibi modern framework'ler kendi tip tanımlarını sağlar (örn. vite/client.d.ts). Bu framework'leri kullanıyorsanız wildcard modül tanımlarını genellikle kendiniz yazmanız gerekmez.

Sonuç

Declaration file'lar, TypeScript ekosisteminin vazgeçilmez bir parçasıdır. Mevcut JavaScript kütüphanelerine tip güvenliği eklemek, global tipleri tanımlamak ve modülleri genişletmek için kullanılır. @types paketleri çoğu popüler kütüphane için tip desteği sağlarken, özel durumlar için kendi declaration file'larınızı oluşturabilirsiniz.

Kaynaklar

İlgili Yazılar