Türkçe

Daha temiz, sürdürülebilir ve tip güvenli kod yazmak için TypeScript yardımcı tiplerinin gücünü keşfedin. Dünya çapındaki geliştiriciler için gerçek dünya örnekleriyle pratik uygulamaları inceleyin.

TypeScript Yardımcı Tiplerinde Uzmanlaşma: Global Geliştiriciler için Pratik Bir Rehber

TypeScript, kodunuzun tip güvenliğini, okunabilirliğini ve sürdürülebilirliğini önemli ölçüde artırabilen güçlü bir yerleşik yardımcı tipler seti sunar. Bu yardımcı tipler, mevcut tiplere uygulayabileceğiniz, sizi tekrarlayan ve hataya açık kod yazmaktan kurtaran, önceden tanımlanmış tip dönüşümleridir. Bu rehber, dünya genelindeki geliştiricilere hitap eden pratik örneklerle çeşitli yardımcı tipleri inceleyecektir.

Neden Yardımcı Tipler Kullanılmalı?

Yardımcı tipler, yaygın tip manipülasyonu senaryolarını ele alır. Bunlardan yararlanarak şunları yapabilirsiniz:

Temel Yardımcı Tipler

Partial

Partial, T'nin tüm özelliklerinin isteğe bağlı (optional) olarak ayarlandığı bir tip oluşturur. Bu, özellikle kısmi güncellemeler veya yapılandırma nesneleri için bir tip oluşturmak istediğinizde kullanışlıdır.

Örnek:

Farklı bölgelerden müşterileri olan bir e-ticaret platformu oluşturduğunuzu hayal edin. Bir Customer tipiniz var:


interface Customer {
  id: string;
  firstName: string;
  lastName: string;
  email: string;
  phoneNumber: string;
  address: {
    street: string;
    city: string;
    country: string;
    postalCode: string;
  };
  preferences?: {
    language: string;
    currency: string;
  }
}

Bir müşterinin bilgilerini güncellerken, tüm alanları zorunlu kılmak istemeyebilirsiniz. Partial, Customer'ın tüm özelliklerinin isteğe bağlı olduğu bir tip tanımlamanıza olanak tanır:


type PartialCustomer = Partial<Customer>;

function updateCustomer(id: string, updates: PartialCustomer): void {
  // ... müşteriyi verilen ID ile güncellemek için implementasyon
}

updateCustomer("123", { firstName: "John", lastName: "Doe" }); // Geçerli
updateCustomer("456", { address: { city: "London" } }); // Geçerli

Readonly

Readonly, T'nin tüm özelliklerinin readonly (salt okunur) olarak ayarlandığı bir tip oluşturur ve başlangıçtan sonra değiştirilmesini engeller. Bu, değişmezliği (immutability) sağlamak için değerlidir.

Örnek:

Global uygulamanız için bir yapılandırma nesnesi düşünün:


interface AppConfig {
  apiUrl: string;
  theme: string;
  supportedLanguages: string[];
  version: string; // Sürüm eklendi
}

const config: AppConfig = {
  apiUrl: "https://api.example.com",
  theme: "dark",
  supportedLanguages: ["en", "fr", "de", "es", "zh"],
  version: "1.0.0"
};

Yapılandırmanın başlangıçtan sonra yanlışlıkla değiştirilmesini önlemek için Readonly kullanabilirsiniz:


type ReadonlyAppConfig = Readonly<AppConfig>;

const readonlyConfig: ReadonlyAppConfig = {
  apiUrl: "https://api.example.com",
  theme: "dark",
  supportedLanguages: ["en", "fr", "de", "es", "zh"],
  version: "1.0.0"
};

// readonlyConfig.apiUrl = "https://newapi.example.com"; // Hata: 'apiUrl' bir salt okunur özellik olduğu için atama yapılamaz.

Pick

Pick, T'den K özellik setini seçerek bir tip oluşturur; burada K, dahil etmek istediğiniz özellik adlarını temsil eden bir dize değişmez tipleri birliğidir (union).

Örnek:

Çeşitli özelliklere sahip bir Event arayüzünüz olduğunu varsayalım:


interface Event {
  id: string;
  title: string;
  description: string;
  location: string;
  startTime: Date;
  endTime: Date;
  organizer: string;
  attendees: string[];
}

Belirli bir görüntüleme bileşeni için yalnızca title, location ve startTime'a ihtiyacınız varsa, Pick kullanabilirsiniz:


type EventSummary = Pick<Event, "title" | "location" | "startTime">;

function displayEventSummary(event: EventSummary): void {
  console.log(`Etkinlik: ${event.title}, Yer: ${event.location}, Tarih: ${event.startTime}`);
}

Omit

Omit, T'den K özellik setini hariç tutarak bir tip oluşturur; burada K, hariç tutmak istediğiniz özellik adlarını temsil eden bir dize değişmez tipleri birliğidir. Bu, Pick'in tam tersidir.

Örnek:

Aynı Event arayüzünü kullanarak, yeni etkinlikler oluşturmak için bir tip oluşturmak isterseniz, genellikle arka uç (backend) tarafından oluşturulan id özelliğini hariç tutmak isteyebilirsiniz:


type NewEvent = Omit<Event, "id">;

function createEvent(event: NewEvent): void {
  // ... yeni bir etkinlik oluşturmak için implementasyon
}

Record

Record, özellik anahtarları K ve özellik değerleri T olan bir nesne tipi oluşturur. K, dize değişmez tipleri, sayı değişmez tipleri veya bir sembol birliği olabilir. Bu, sözlükler veya haritalar (map) oluşturmak için mükemmeldir.

Örnek:

Uygulamanızın kullanıcı arayüzü için çevirileri saklamanız gerektiğini düşünün. Çevirileriniz için bir tip tanımlamak üzere Record kullanabilirsiniz:


type Translations = Record<string, string>;

const enTranslations: Translations = {
  "hello": "Hello",
  "goodbye": "Goodbye",
  "welcome": "Welcome to our platform!"
};

const frTranslations: Translations = {
  "hello": "Bonjour",
  "goodbye": "Au revoir",
  "welcome": "Bienvenue sur notre plateforme !"
};

function translate(key: string, language: string): string {
  const translations = language === "en" ? enTranslations : frTranslations; //Basitleştirilmiş
  return translations[key] || key; // Çeviri bulunamazsa anahtara geri dön
}

console.log(translate("hello", "en")); // Çıktı: Hello
console.log(translate("hello", "fr")); // Çıktı: Bonjour
console.log(translate("nonexistent", "en")); // Çıktı: nonexistent

Exclude

Exclude, T'den U'ya atanabilen tüm birleşim (union) üyelerini hariç tutarak bir tip oluşturur. Belirli tipleri bir birleşimden filtrelemek için kullanışlıdır.

Örnek:

Farklı etkinlik türlerini temsil eden bir tipiniz olabilir:


type EventType = "concert" | "conference" | "workshop" | "webinar";

"webinar" etkinliklerini hariç tutan bir tip oluşturmak isterseniz, Exclude kullanabilirsiniz:


type PhysicalEvent = Exclude<EventType, "webinar">;

// PhysicalEvent artık "concert" | "conference" | "workshop" oldu

function attendPhysicalEvent(event: PhysicalEvent): void {
  console.log(`${event} etkinliğine katılım sağlandı`);
}

// attendPhysicalEvent("webinar"); // Hata: '"webinar"' türündeki argüman, '"concert" | "conference" | "workshop"' türündeki parametreye atanamaz.

attendPhysicalEvent("concert"); // Geçerli

Extract

Extract, T'den U'ya atanabilen tüm birleşim üyelerini çıkararak bir tip oluşturur. Bu, Exclude'in tam tersidir.

Örnek:

Aynı EventType'ı kullanarak, webinar etkinlik türünü çıkarabilirsiniz:


type OnlineEvent = Extract<EventType, "webinar">;

// OnlineEvent artık "webinar" oldu

function attendOnlineEvent(event: OnlineEvent): void {
  console.log(`Çevrimiçi olarak bir ${event} etkinliğine katılım sağlandı`);
}

attendOnlineEvent("webinar"); // Geçerli
// attendOnlineEvent("concert"); // Hata: '"concert"' türündeki argüman, '"webinar"' türündeki parametreye atanamaz.

NonNullable

NonNullable, T'den null ve undefined'ı hariç tutarak bir tip oluşturur.

Örnek:


type MaybeString = string | null | undefined;

type DefinitelyString = NonNullable<MaybeString>;

// DefinitelyString artık string oldu

function processString(str: DefinitelyString): void {
  console.log(str.toUpperCase());
}

// processString(null); // Hata: 'null' türündeki argüman, 'string' türündeki parametreye atanamaz.
// processString(undefined); // Hata: 'undefined' türündeki argüman, 'string' türündeki parametreye atanamaz.
processString("hello"); // Geçerli

ReturnType

ReturnType, T fonksiyonunun dönüş tipinden oluşan bir tip oluşturur.

Örnek:


function greet(name: string): string {
  return `Merhaba, ${name}!`;
}

type Greeting = ReturnType<typeof greet>;

// Greeting artık string oldu

const message: Greeting = greet("Dünya");

console.log(message);

Parameters

Parameters, bir T fonksiyon tipinin parametrelerinin tiplerinden bir demet (tuple) tipi oluşturur.

Örnek:


function logEvent(eventName: string, eventData: object): void {
  console.log(`Etkinlik: ${eventName}`, eventData);
}

type LogEventParams = Parameters<typeof logEvent>;

// LogEventParams artık [eventName: string, eventData: object] oldu

const params: LogEventParams = ["user_login", { userId: "123", timestamp: Date.now() }];

logEvent(...params);

ConstructorParameters

ConstructorParameters, bir T kurucu fonksiyon tipinin parametrelerinin tiplerinden bir demet veya dizi tipi oluşturur. Bir sınıfın kurucusuna (constructor) geçirilmesi gereken argümanların tiplerini çıkarır.

Örnek:


class Greeter {
  greeting: string;

  constructor(message: string) {
    this.greeting = message;
  }

  greet() {
    return "Merhaba, " + this.greeting;
  }
}


type GreeterParams = ConstructorParameters<typeof Greeter>;

// GreeterParams artık [message: string] oldu

const paramsGreeter: GreeterParams = ["Dünya"];
const greeterInstance = new Greeter(...paramsGreeter);

console.log(greeterInstance.greet()); // Çıktı: Merhaba, Dünya

Required

Required, T'nin tüm özelliklerinin zorunlu olarak ayarlandığı bir tip oluşturur. Tüm isteğe bağlı özellikleri zorunlu hale getirir.

Örnek:


interface UserProfile {
  name: string;
  age?: number;
  email?: string;
}

type RequiredUserProfile = Required<UserProfile>;

// RequiredUserProfile artık { name: string; age: number; email: string; } oldu

const completeProfile: RequiredUserProfile = {
  name: "Alice",
  age: 30,
  email: "alice@example.com"
};

// const incompleteProfile: RequiredUserProfile = { name: "Bob" }; // Hata: '{ name: string; }' tipinde 'age' özelliği eksik ancak 'Required' tipinde zorunlu.

İleri Düzey Yardımcı Tipler

Şablon Değişmez Tipleri (Template Literal Types)

Şablon değişmez tipleri, mevcut dize değişmez tiplerini, sayı değişmez tiplerini ve daha fazlasını birleştirerek yeni dize değişmez tipleri oluşturmanıza olanak tanır. Bu, güçlü dize tabanlı tip manipülasyonu sağlar.

Örnek:


type HTTPMethod = "GET" | "POST" | "PUT" | "DELETE";
type APIEndpoint = `/api/users` | `/api/products`;

type RequestURL = `${HTTPMethod} ${APIEndpoint}`;

// RequestURL artık "GET /api/users" | "POST /api/users" | "PUT /api/users" | "DELETE /api/users" | "GET /api/products" | "POST /api/products" | "PUT /api/products" | "DELETE /api/products" oldu

function makeRequest(url: RequestURL): void {
  console.log(`${url} adresine istek yapılıyor`);
}

makeRequest("GET /api/users"); // Geçerli
// makeRequest("INVALID /api/users"); // Hata

Koşullu Tipler (Conditional Types)

Koşullu tipler, bir tip ilişkisi olarak ifade edilen bir koşula bağlı tipler tanımlamanıza olanak tanır. Tip bilgilerini çıkarmak için infer anahtar kelimesini kullanırlar.

Örnek:


type UnwrapPromise<T> = T extends Promise<infer U> ? U : T;

// Eğer T bir Promise ise, tip U olur; aksi takdirde, tip T olur.

async function fetchData(): Promise<number> {
  return 42;
}


type Data = UnwrapPromise<ReturnType<typeof fetchData>>;

// Data artık number oldu

function processData(data: Data): void {
  console.log(data * 2);
}

processData(await fetchData());

Pratik Uygulamalar ve Gerçek Dünya Senaryoları

Yardımcı tiplerin öne çıktığı daha karmaşık gerçek dünya senaryolarını keşfedelim.

1. Form Yönetimi

Formlarla uğraşırken, genellikle başlangıç form değerlerini, güncellenmiş form değerlerini ve son gönderilen değerleri temsil etmeniz gereken senaryolarla karşılaşırsınız. Yardımcı tipler, bu farklı durumları verimli bir şekilde yönetmenize yardımcı olabilir.


interface FormData {
  firstName: string;
  lastName: string;
  email: string;
  country: string; // Zorunlu
  city?: string; // İsteğe Bağlı
  postalCode?: string;
  newsletterSubscription?: boolean;
}

// Başlangıç form değerleri (isteğe bağlı alanlar)
type InitialFormValues = Partial<FormData>;

// Güncellenmiş form değerleri (bazı alanlar eksik olabilir)
type UpdatedFormValues = Partial<FormData>;

// Gönderim için zorunlu alanlar
type RequiredForSubmission = Required<Pick<FormData, 'firstName' | 'lastName' | 'email' | 'country'>>;

// Bu tipleri form bileşenlerinizde kullanın
function initializeForm(initialValues: InitialFormValues): void { }
function updateForm(updates: UpdatedFormValues): void {}
function submitForm(data: RequiredForSubmission): void {}


const initialForm: InitialFormValues = { newsletterSubscription: true };

const updateFormValues: UpdatedFormValues = {
    firstName: "John",
    lastName: "Doe"
};

// const submissionData: RequiredForSubmission = { firstName: "test", lastName: "test", email: "test" }; // HATA: 'country' eksik 
const submissionData: RequiredForSubmission = { firstName: "test", lastName: "test", email: "test", country: "USA" }; //TAMAM


2. API Veri Dönüşümü

Bir API'den veri alırken, veriyi uygulamanız için farklı bir formata dönüştürmeniz gerekebilir. Yardımcı tipler, dönüştürülmüş verinin yapısını tanımlamanıza yardımcı olabilir.


interface APIResponse {
  user_id: string;
  first_name: string;
  last_name: string;
  email_address: string;
  profile_picture_url: string;
  is_active: boolean;
}

// API yanıtını daha okunabilir bir formata dönüştürün
type UserData = {
  id: string;
  fullName: string;
  email: string;
  avatar: string;
  active: boolean;
};

function transformApiResponse(response: APIResponse): UserData {
  return {
    id: response.user_id,
    fullName: `${response.first_name} ${response.last_name}`,
    email: response.email_address,
    avatar: response.profile_picture_url,
    active: response.is_active
  };
}

function fetchAndTransformData(url: string): Promise<UserData> {
    return fetch(url)
        .then(response => response.json())
        .then(data => transformApiResponse(data));
}


// Hatta tipi şu şekilde zorunlu kılabilirsiniz:

function saferTransformApiResponse(response: APIResponse): UserData {
    const {user_id, first_name, last_name, email_address, profile_picture_url, is_active} = response;
    const transformed: UserData = {
        id: user_id,
        fullName: `${first_name} ${last_name}`,
        email: email_address,
        avatar: profile_picture_url,
        active: is_active
    };

    return transformed;
}

3. Yapılandırma Nesnelerini Yönetme

Yapılandırma nesneleri birçok uygulamada yaygındır. Yardımcı tipler, yapılandırma nesnesinin yapısını tanımlamanıza ve doğru kullanılmasını sağlamanıza yardımcı olabilir.


interface AppSettings {
  theme: "light" | "dark";
  language: string;
  notificationsEnabled: boolean;
  apiUrl?: string; // Farklı ortamlar için isteğe bağlı API URL'si
  timeout?: number;  //İsteğe Bağlı
}

// Varsayılan ayarlar
const defaultSettings: AppSettings = {
  theme: "light",
  language: "en",
  notificationsEnabled: true
};

// Kullanıcı ayarlarını varsayılan ayarlarla birleştiren fonksiyon
function mergeSettings(userSettings: Partial<AppSettings>): AppSettings {
  return { ...defaultSettings, ...userSettings };
}

// Birleştirilmiş ayarları uygulamanızda kullanın
const mergedSettings = mergeSettings({ theme: "dark", apiUrl: "https://customapi.example.com" });
console.log(mergedSettings);

Yardımcı Tiplerin Etkili Kullanımı için İpuçları

  • Basit başlayın: Daha karmaşık olanlara geçmeden önce Partial ve Readonly gibi temel yardımcı tiplerle başlayın.
  • Açıklayıcı isimler kullanın: Okunabilirliği artırmak için tip takma adlarınıza (type alias) anlamlı isimler verin.
  • Yardımcı tipleri birleştirin: Karmaşık tip dönüşümleri elde etmek için birden fazla yardımcı tipi birleştirebilirsiniz.
  • Editör desteğinden yararlanın: Yardımcı tiplerin etkilerini keşfetmek için TypeScript'in mükemmel editör desteğinden faydalanın.
  • Temel kavramları anlayın: TypeScript'in tip sistemini sağlam bir şekilde anlamak, yardımcı tiplerin etkili kullanımı için esastır.

Sonuç

TypeScript yardımcı tipleri, kodunuzun kalitesini ve sürdürülebilirliğini önemli ölçüde artırabilen güçlü araçlardır. Bu yardımcı tipleri etkili bir şekilde anlayıp uygulayarak, global bir geliştirme ortamının taleplerini karşılayan daha temiz, daha tip güvenli ve daha sağlam uygulamalar yazabilirsiniz. Bu rehber, yaygın yardımcı tipler ve pratik örnekler hakkında kapsamlı bir genel bakış sunmuştur. Onlarla denemeler yapın ve TypeScript projelerinizi geliştirmek için potansiyellerini keşfedin. Yardımcı tipleri kullanırken okunabilirliği ve netliği önceliklendirmeyi unutmayın ve her zaman, diğer geliştiricilerinizin nerede olursa olsun, anlaşılması ve bakımı kolay kod yazmaya çalışın.

TypeScript Yardımcı Tiplerinde Uzmanlaşma: Global Geliştiriciler için Pratik Bir Rehber | MLOG