Türkçe

Küresel geliştirme ortamı için sağlam ve tür-güvenli uygulamalar oluşturmak amacıyla TypeScript'in güçlü şablon değişmez türlerine ve dize işleme araçlarına derinlemesine dalın.

TypeScript Şablon Dizi Deseni: Gelişmiş Dizi İşleme Türlerini Ortaya Çıkarma

Yazılım geliştirmenin geniş ve sürekli gelişen dünyasında, hassasiyet ve tür güvenliği her şeyden önemlidir. JavaScript'in bir üst kümesi olan TypeScript, özellikle çeşitli küresel ekiplerle çalışırken ölçeklenebilir ve sürdürülebilir uygulamalar oluşturmak için kritik bir araç olarak ortaya çıkmıştır. TypeScript'in temel gücü statik tipleme yeteneklerinde yatsa da, genellikle hafife alınan bir alan, özellikle "şablon değişmez türleri" aracılığıyla dizeleri sofistike bir şekilde işlemesidir.

Bu kapsamlı rehber, TypeScript'in geliştiricilere derleme zamanında dize desenlerini nasıl tanımlama, işleme ve doğrulama gücü verdiğini derinlemesine ele alacak ve bu sayede daha sağlam ve hataya dayanıklı kod tabanları oluşturulmasını sağlayacaktır. Temel kavramları keşfedecek, güçlü yardımcı türleri tanıtacak ve herhangi bir uluslararası projede geliştirme iş akışlarını önemli ölçüde geliştirebilecek pratik, gerçek dünya uygulamalarını göstereceğiz. Bu makalenin sonunda, daha hassas ve öngörülebilir sistemler oluşturmak için bu gelişmiş TypeScript özelliklerinden nasıl yararlanacağınızı anlayacaksınız.

Şablon Değişmezlerini Anlamak: Tür Güvenliği İçin Bir Temel

Tür düzeyindeki sihire dalmadan önce, TypeScript'in gelişmiş dize türlerinin sözdizimsel temelini oluşturan JavaScript'in şablon değişmezlerini (ES6'da tanıtıldı) kısaca tekrar gözden geçirelim. Şablon değişmezleri, ters tırnak (` `) içine alınır ve gömülü ifadelere (${expression}) ve çok satırlı dizelere izin vererek, geleneksel birleştirmeye kıyasla dize oluşturmak için daha kullanışlı ve okunabilir bir yol sunar.

JavaScript/TypeScript'te Temel Sözdizimi ve Kullanımı

Basit bir selamlama düşünün:

// JavaScript / TypeScript

const userName = "Alice";

const age = 30;

const greeting = `Merhaba, ${userName}! ${age} yaşındasınız. Küresel platformumuza hoş geldiniz.`;

console.log(greeting); // Çıktı: "Merhaba, Alice! 30 yaşındasınız. Küresel platformumuza hoş geldiniz."

Bu örnekte, ${userName} ve ${age} gömülü ifadelerdir. TypeScript, greeting türünü string olarak çıkarır. Basit olmasına rağmen, bu sözdizimi kritik öneme sahiptir çünkü TypeScript'in şablon değişmez türleri bunu yansıtır ve yalnızca genel dizeler yerine belirli dize desenlerini temsil eden türler oluşturmanıza olanak tanır.

Dize Değişmez Türleri: Hassasiyetin Yapı Taşları

TypeScript, bir değişkenin yalnızca belirli, tam bir dize değeri tutabileceğini belirtmenize olanak tanıyan dize değişmez türlerini tanıttı. Bu, neredeyse bir enum gibi davranan ancak doğrudan dize temsili esnekliğine sahip olan son derece spesifik tür kısıtlamaları oluşturmak için inanılmaz derecede kullanışlıdır.

// TypeScript

type Status = "pending" | "success" | "failed";

function updateOrderStatus(orderId: string, status: Status) {

if (status === "success") {

console.log(`Sipariş ${orderId} başarıyla işlendi.`);

} else if (status === "pending") {

console.log(`Sipariş ${orderId} işlem için bekleniyor.`);

} else {

console.log(`Sipariş ${orderId} işlenemedi.`);

}

}

updateOrderStatus("ORD-123", "success"); // Geçerli

// updateOrderStatus("ORD-456", "in-progress"); // Tür Hatası: '"in-progress"' türündeki argüman, 'Status' türündeki parametreye atanamaz.

// updateOrderStatus("ORD-789", "succeeded"); // Tür Hatası: 'succeeded' değişmez türlerden biri değil.

Bu basit konsept, şablon değişmez türlerimizin değişmez kısımlarını hassas bir şekilde tanımlamamıza izin verdiği için daha karmaşık dize desenlerini tanımlamanın temelini oluşturur. Belirli dize değerlerine bağlı kalınmasını garanti eder, bu da büyük, dağıtılmış bir uygulamada farklı modüller veya hizmetler arasında tutarlılığı korumak için paha biçilmezdir.

TypeScript'in Şablon Değişmez Türleriyle Tanışın (TS 4.1+)

Dize işleme türlerindeki gerçek devrim, TypeScript 4.1'in "Şablon Değişmez Türleri"ni tanıtmasıyla geldi. Bu özellik, belirli dize desenleriyle eşleşen türler tanımlamanıza olanak tanıyarak, dize bileşimine dayalı güçlü derleme zamanı doğrulaması ve tür çıkarımı sağlar. Önemli olan, bunların tür seviyesinde çalışan, JavaScript'in şablon değişmezlerinin çalışma zamanı dize oluşturmasından farklı olan, ancak aynı sözdizimini paylaşan türler olmasıdır.

Bir şablon değişmez türü, çalışma zamanındaki bir şablon değişmezine sözdizimsel olarak benzer görünür, ancak tamamen tür sistemi içinde çalışır. Dize değişmez türlerini diğer türler için yer tutucularla (string, number, boolean, bigint gibi) birleştirerek yeni dize değişmez türleri oluşturmaya olanak tanır. Bu, TypeScript'in tam dize formatını anlayıp doğrulayabileceği anlamına gelir, bu da yanlış biçimlendirilmiş tanımlayıcılar veya standartlaştırılmamış anahtarlar gibi sorunları önler.

Temel Şablon Değişmez Türü Sözdizimi

Bir tür tanımı içinde ters tırnak (` `) ve yer tutucular (${Type}) kullanırız:

// TypeScript

type UserPrefix = "user";

type ItemPrefix = "item";

type ResourceId = `${UserPrefix | ItemPrefix}_${string}`;

let userId: ResourceId = "user_12345"; // Geçerli: "user_${string}" ile eşleşiyor

let itemId: ResourceId = "item_ABC-XYZ"; // Geçerli: "item_${string}" ile eşleşiyor

// let invalidId: ResourceId = "product_789"; // Tür Hatası: '"product_789"' türü, '"user_${string}" | "item_${string}"' türüne atanamaz.

// Bu hata, çalışma zamanında değil derleme zamanında yakalanarak potansiyel bir hatayı önler.

Bu örnekte, ResourceId iki şablon değişmez türünün bir birleşimidir: "user_${string}" ve "item_${string}". Bu, ResourceId'ye atanan herhangi bir dizenin "user_" veya "item_" ile başlaması ve ardından herhangi bir dizenin gelmesi gerektiği anlamına gelir. Bu, kimliklerinizin formatı hakkında anında, derleme zamanı garantisi sağlar ve büyük bir uygulama veya dağıtılmış bir ekip genelinde tutarlılık sağlar.

Şablon Değişmez Türleri ile infer'in Gücü

Şablon değişmez türlerinin koşullu türlerle birleştirildiğinde en güçlü yönlerinden biri, dize deseninin bölümlerini çıkarma yeteneğidir. infer anahtar kelimesi, bir yer tutucuyla eşleşen dizenin bir bölümünü yakalamanıza olanak tanır ve bunu koşullu tür içinde yeni bir tür değişkeni olarak kullanılabilir hale getirir. Bu, doğrudan tür tanımlarınız içinde sofistike desen eşleştirme ve çıkarma sağlar.

// TypeScript

type GetPrefix = T extends `${infer Prefix}_${string}` ? Prefix : never;

type UserType = GetPrefix<"user_data_123">

// UserType "user" olur

type ItemType = GetPrefix<"item_details_XYZ">

// ItemType "item" olur

type FallbackPrefix = GetPrefix<"just_a_string">

// FallbackPrefix "just" olur (çünkü "just_a_string", `${infer Prefix}_${string}` ile eşleşir)

type NoMatch = GetPrefix<"simple_string_without_underscore">

// NoMatch "simple_string_without_underscore" olur (desen en az bir alt çizgi gerektirdiğinden)

// Düzeltme: `${infer Prefix}_${string}` deseni, "herhangi bir dize, ardından bir alt çizgi, ardından herhangi bir dize" anlamına gelir.

// Eğer "simple_string_without_underscore" bir alt çizgi içermiyorsa, bu desenle eşleşmez.

// Bu nedenle, eğer gerçekten alt çizgi yoksa, bu senaryoda NoMatch `never` olurdu.

// Önceki örneğim, `infer`'in isteğe bağlı kısımlarla nasıl çalıştığı konusunda yanlıştı. Bunu düzeltelim.

// Daha hassas bir GetPrefix örneği:

type GetLeadingPart = T extends `${infer PartA}_${infer PartB}` ? PartA : T;

type UserPart = GetLeadingPart<"user_data">

// UserPart "user" olur

type SinglePart = GetLeadingPart<"alone">

// SinglePart "alone" olur (alt çizgili desenle eşleşmez, bu yüzden T'yi döndürür)

// Belirli bilinen önekler için hassaslaştıralım

type KnownCategory = "product" | "order" | "customer";

type ExtractCategory = T extends `${infer Category extends KnownCategory}_${string}` ? Category : never;

type MyProductCategory = ExtractCategory<"product_details_001">

// MyProductCategory "product" olur

type MyCustomerCategory = ExtractCategory<"customer_profile_abc">

// MyCustomerCategory "customer" olur

type UnknownCategory = ExtractCategory<"vendor_item_xyz">

// UnknownCategory 'never' olur ("vendor", KnownCategory içinde olmadığı için)

infer anahtar kelimesi, özellikle kısıtlamalarla (infer P extends KnownPrefix) birleştirildiğinde, karmaşık dize desenlerini tür seviyesinde ayrıştırmak ve doğrulamak için son derece güçlüdür. Bu, tıpkı bir çalışma zamanı ayrıştırıcısı gibi bir dizenin bölümlerini ayrıştırabilen ve anlayabilen, ancak derleme zamanı güvenliği ve sağlam otomatik tamamlama gibi ek avantajlara sahip olan oldukça akıllı tür tanımları oluşturmaya olanak tanır.

Gelişmiş Dize İşleme Yardımcı Türleri (TS 4.1+)

Şablon değişmez türlerinin yanı sıra, TypeScript 4.1 aynı zamanda bir dizi içsel dize işleme yardımcı türü de tanıttı. Bu türler, dize değişmez türlerini diğer dize değişmez türlerine dönüştürmenize olanak tanıyarak, tür seviyesinde dize büyük/küçük harf kullanımı ve biçimlendirme üzerinde benzersiz bir kontrol sağlar. Bu, çeşitli kod tabanları ve ekipler arasında katı adlandırma kurallarını zorlamak, çeşitli programlama paradigmaları veya kültürel tercihler arasındaki potansiyel stil farklılıklarını köprülemek için özellikle değerlidir.

Bu yardımcı programlar, adlandırma kurallarını zorlamak, API verilerini dönüştürmek veya küresel geliştirme ekiplerinde yaygın olarak bulunan çeşitli adlandırma stilleriyle çalışmak için inanılmaz derecede kullanışlıdır ve bir ekip üyesinin camelCase, PascalCase, snake_case veya kebab-case'i tercih edip etmemesine bakılmaksızın tutarlılık sağlar.

Dize İşleme Yardımcı Türleri Örnekleri

// TypeScript

type ProductName = "global_product_identifier";

type UppercaseProductName = Uppercase;

// UppercaseProductName "GLOBAL_PRODUCT_IDENTIFIER" olur

type LowercaseServiceName = Lowercase<"SERVICE_CLIENT_API">

// LowercaseServiceName "service_client_api" olur

type FunctionName = "initConnection";

type CapitalizedFunctionName = Capitalize;

// CapitalizedFunctionName "InitConnection" olur

type ClassName = "UserDataProcessor";

type UncapitalizedClassName = Uncapitalize;

// UncapitalizedClassName "userDataProcessor" olur

Şablon Değişmez Türlerini Yardımcı Türlerle Birleştirmek

Gerçek güç, bu özellikler birleştirildiğinde ortaya çıkar. Belirli büyük/küçük harf kullanımını gerektiren türler oluşturabilir veya mevcut dize değişmez türlerinin dönüştürülmüş bölümlerine dayalı yeni türler üretebilirsiniz, bu da son derece esnek ve sağlam tür tanımları sağlar.

// TypeScript

type HttpMethod = "get" | "post" | "put" | "delete";

type EntityType = "User" | "Product" | "Order";

// Örnek 1: Tür-güvenli REST API uç noktası eylem adları (örn. GET_USER, POST_PRODUCT)

type ApiAction = `${Uppercase}_${Uppercase}`;

let getUserAction: ApiAction = "GET_USER";

let createProductAction: ApiAction = "POST_PRODUCT";

// let invalidAction: ApiAction = "get_user"; // Tür Hatası: 'get' ve 'user' için büyük/küçük harf uyumsuzluğu.

// let unknownAction: ApiAction = "DELETE_REPORT"; // Tür Hatası: 'REPORT', EntityType içinde değil.

// Örnek 2: Kurala dayalı bileşen olay adları oluşturma (örn. "OnSubmitForm", "OnClickButton")

type ComponentName = "Form" | "Button" | "Modal";

type EventTrigger = "submit" | "click" | "close" | "change";

type ComponentEvent = `On${Capitalize}${ComponentName}`;

// ComponentEvent "OnSubmitForm" | "OnClickForm" | ... | "OnChangeModal" olur

let formSubmitEvent: ComponentEvent = "OnSubmitForm";

let buttonClickEvent: ComponentEvent = "OnClickButton";

// let modalOpenEvent: ComponentEvent = "OnOpenModal"; // Tür Hatası: 'open', EventTrigger içinde değil.

// Örnek 3: Belirli bir önek ve camelCase dönüşümü ile CSS değişken adlarını tanımlama

type CssVariableSuffix = "primaryColor" | "secondaryBackground" | "fontSizeBase";

type CssVariableName = `--app-${Uncapitalize}`;

// CssVariableName "--app-primaryColor" | "--app-secondaryBackground" | "--app-fontSizeBase" olur

let colorVar: CssVariableName = "--app-primaryColor";

// let invalidVar: CssVariableName = "--app-PrimaryColor"; // Tür Hatası: 'PrimaryColor' için büyük/küçük harf uyumsuzluğu.

Küresel Yazılım Geliştirmede Pratik Uygulamalar

TypeScript'in dize işleme türlerinin gücü, teorik örneklerin çok ötesine uzanır. Özellikle farklı zaman dilimlerinde ve kültürel geçmişlere sahip dağıtılmış ekipleri içeren büyük ölçekli projelerde tutarlılığı korumak, hataları azaltmak ve geliştirici deneyimini iyileştirmek için somut faydalar sunarlar. Dize desenlerini kodlayarak, ekipler tür sistemi aracılığıyla daha etkili bir şekilde iletişim kurabilir, bu da karmaşık projelerde sıkça ortaya çıkan belirsizlikleri ve yanlış yorumlamaları azaltır.

1. Tür-Güvenli API Uç Noktası Tanımları ve İstemci Oluşturma

Sağlam API istemcileri oluşturmak, mikro hizmet mimarileri veya harici hizmetlerle entegrasyon için çok önemlidir. Şablon değişmez türleriyle, API uç noktalarınız için kesin desenler tanımlayabilir, geliştiricilerin doğru URL'ler oluşturmasını ve beklenen veri türlerinin uyumlu olmasını sağlayabilirsiniz. Bu, bir kuruluş genelinde API çağrılarının nasıl yapıldığını ve belgelendiğini standartlaştırır.

// TypeScript

type BaseUrl = "https://api.mycompany.com";

type ApiVersion = "v1" | "v2";

type Resource = "users" | "products" | "orders";

type UserPathSegment = "profile" | "settings" | "activity";

type ProductPathSegment = "details" | "inventory" | "reviews";

// Belirli desenlerle olası uç noktası yollarını tanımlayın

type EndpointPath =

`${Resource}` |

`${Resource}/${string}` |

`users/${string}/${UserPathSegment}` |

`products/${string}/${ProductPathSegment}`;

// Temel, sürüm ve yolu birleştiren tam API URL türü

type ApiUrl = `${BaseUrl}/${ApiVersion}/${EndpointPath}`;

function fetchApiData(url: ApiUrl) {

console.log(`Veri çekilmeye çalışılıyor: ${url}`);

// ... gerçek ağ getirme mantığı buraya gelirdi ...

return Promise.resolve(`${url} adresinden veri`);

}

fetchApiData("https://api.mycompany.com/v1/users"); // Geçerli: Temel kaynak listesi

fetchApiData("https://api.mycompany.com/v2/products/PROD-001/details"); // Geçerli: Belirli ürün detayı

fetchApiData("https://api.mycompany.com/v1/users/user-123/profile"); // Geçerli: Belirli kullanıcı profili

// Tür Hatası: Yol, tanımlanan desenlerle eşleşmiyor veya temel URL/sürüm yanlış

// fetchApiData("https://api.mycompany.com/v3/orders"); // 'v3' geçerli bir ApiVersion değil

// fetchApiData("https://api.mycompany.com/v1/users/user-123/dashboard"); // 'dashboard' UserPathSegment içinde değil

// fetchApiData("https://api.mycompany.com/v1/reports"); // 'reports' geçerli bir Kaynak değil

Bu yaklaşım, geliştirme sırasında anında geri bildirim sağlayarak yaygın API entegrasyon hatalarını önler. Küresel olarak dağıtılmış ekipler için bu, yanlış yapılandırılmış URL'leri ayıklamak için daha az zaman harcanması ve özellik oluşturmaya daha fazla zaman ayrılması anlamına gelir, çünkü tür sistemi API tüketicileri için evrensel bir kılavuz görevi görür.

2. Tür-Güvenli Olay Adlandırma Kuralları

Büyük uygulamalarda, özellikle mikro hizmetlere veya karmaşık kullanıcı arayüzü etkileşimlerine sahip olanlarda, tutarlı bir olay adlandırma stratejisi net iletişim ve hata ayıklama için hayati önem taşır. Şablon değişmez türleri bu desenleri zorlayabilir, olay üreticilerinin ve tüketicilerinin birleşik bir sözleşmeye uymasını sağlar.

// TypeScript

type EventDomain = "USER" | "PRODUCT" | "ORDER" | "ANALYTICS";

type EventAction = "CREATED" | "UPDATED" | "DELETED" | "VIEWED" | "SENT" | "RECEIVED";

type EventTarget = "ACCOUNT" | "ITEM" | "FULFILLMENT" | "REPORT";

// Standart bir olay adı formatı tanımlayın: DOMAIN_ACTION_TARGET (örn. USER_CREATED_ACCOUNT)

type SystemEvent = `${Uppercase}_${Uppercase}_${Uppercase}`;

function publishEvent(eventName: SystemEvent, payload: unknown) {

console.log(`Olay yayınlanıyor: "${eventName}", veri:`, payload);

// ... gerçek olay yayınlama mekanizması (örn. mesaj kuyruğu) ...

}

publishEvent("USER_CREATED_ACCOUNT", { userId: "uuid-123", email: "test@example.com" }); // Geçerli

publishEvent("PRODUCT_UPDATED_ITEM", { productId: "item-456", newPrice: 99.99 }); // Geçerli

// Tür Hatası: Olay adı gerekli desenle eşleşmiyor

// publishEvent("user_created_account", {}); // Yanlış büyük/küçük harf kullanımı

// publishEvent("ORDER_SHIPPED", {}); // Hedef soneki eksik, 'SHIPPED' EventAction içinde değil

// publishEvent("ADMIN_LOGGED_IN", {}); // 'ADMIN' tanımlı bir EventDomain değil

Bu, tüm olayların önceden tanımlanmış bir yapıya uymasını sağlar, bu da geliştiricinin ana dili veya kodlama stili tercihlerinden bağımsız olarak hata ayıklamayı, izlemeyi ve ekipler arası iletişimi önemli ölçüde kolaylaştırır.

3. Kullanıcı Arayüzü Geliştirmede CSS Yardımcı Sınıf Desenlerini Zorlama

Tasarım sistemleri ve yardımcı program öncelikli CSS çerçeveleri için sınıfların adlandırma kuralları, sürdürülebilirlik ve ölçeklenebilirlik için kritiktir. TypeScript, geliştirme sırasında bunları zorlamaya yardımcı olabilir, bu da tasarımcıların ve geliştiricilerin tutarsız sınıf adları kullanma olasılığını azaltır.

// TypeScript

type SpacingSize = "xs" | "sm" | "md" | "lg" | "xl";

type Direction = "top" | "bottom" | "left" | "right" | "x" | "y" | "all";

type SpacingProperty = "margin" | "padding";

// Örnek: Belirli bir yönde ve boyutta kenar boşluğu veya dolgu için sınıf

// örn. "m-t-md" (margin-top-medium) veya "p-x-lg" (padding-x-large)

type SpacingClass = `${Lowercase}-${Lowercase}-${Lowercase}`;

function applyCssClass(elementId: string, className: SpacingClass) {

const element = document.getElementById(elementId);

if (element) {

element.classList.add(className); console.log(`'${className}' sınıfı '${elementId}' elementine uygulandı`);

} else {

console.warn(`'${elementId}' ID'li element bulunamadı.`);

}

}

applyCssClass("my-header", "m-t-md"); // Geçerli

applyCssClass("product-card", "p-x-lg"); // Geçerli

applyCssClass("main-content", "m-all-xl"); // Geçerli

// Tür Hatası: Sınıf desene uymuyor

// applyCssClass("my-footer", "margin-top-medium"); // Yanlış ayırıcı ve kısaltma yerine tam kelime

// applyCssClass("sidebar", "m-center-sm"); // 'center' geçerli bir Yön değişmezi değil

Bu desen, yanlışlıkla geçersiz veya yanlış yazılmış bir CSS sınıfı kullanmayı imkansız hale getirir, bu da bir ürünün kullanıcı arayüzü genelinde görsel tutarlılığı artırır ve görsel hataları azaltır, özellikle birden fazla geliştirici stil mantığına katkıda bulunduğunda.

4. Uluslararasılaştırma (i18n) Anahtar Yönetimi ve Doğrulaması

Küresel uygulamalarda, yerelleştirme anahtarlarını yönetmek inanılmaz derecede karmaşık hale gelebilir ve genellikle birden çok dilde binlerce giriş içerebilir. Şablon değişmez türleri, hiyerarşik veya açıklayıcı anahtar desenlerini zorlamaya yardımcı olabilir, bu da anahtarların tutarlı ve sürdürülmesinin daha kolay olmasını sağlar.

// TypeScript

type PageKey = "home" | "dashboard" | "settings" | "auth";

type SectionKey = "header" | "footer" | "sidebar" | "form" | "modal" | "navigation";

type MessageType = "label" | "placeholder" | "button" | "error" | "success" | "heading";

// i18n anahtarları için bir desen tanımlayın: page.section.messageType.descriptor

type I18nKey = `${PageKey}.${SectionKey}.${MessageType}.${string}`;

function translate(key: I18nKey, params?: Record): string {

console.log(`Anahtar çevriliyor: "${key}", parametreler:`, params);

// Gerçek bir uygulamada, bu bir çeviri hizmetinden veya yerel bir sözlükten getirmeyi içerir

let translatedString = `[${key}_translated]`;

if (params) {

for (const p in params) {

translatedString = translatedString.replace(`{${p}}`, params[p]);

}

}

return translatedString;

}

console.log(translate("home.header.heading.welcomeUser", { user: "Küresel Gezgin" })); // Geçerli

console.log(translate("dashboard.form.label.username")); // Geçerli

console.log(translate("auth.modal.button.login")); // Geçerli

// Tür Hatası: Anahtar tanımlanan desenle eşleşmiyor

// console.log(translate("home_header_greeting_welcome")); // Yanlış ayırıcı (nokta yerine alt çizgi kullanılıyor)

// console.log(translate("users.profile.label.email")); // 'users' geçerli bir PageKey değil

// console.log(translate("settings.navbar.button.save")); // 'navbar' geçerli bir SectionKey değil ('navigation' veya 'sidebar' olmalı)

Bu, yerelleştirme anahtarlarının tutarlı bir şekilde yapılandırılmasını sağlar, bu da çeşitli diller ve yereller arasında yeni çeviriler ekleme ve mevcut olanları sürdürme sürecini basitleştirir. Anahtarlardaki yazım hataları gibi yaygın hataları önler, bu da kullanıcı arayüzünde çevrilmemiş dizelere yol açabilir, bu da uluslararası kullanıcılar için sinir bozucu bir deneyimdir.

infer ile Gelişmiş Teknikler

infer anahtar kelimesinin gerçek gücü, bir dizenin birden çok bölümünü çıkarmanız, birleştirmeniz veya dinamik olarak dönüştürmeniz gereken daha karmaşık senaryolarda parlar. Bu, son derece esnek ve güçlü tür düzeyinde ayrıştırmaya olanak tanır.

Birden Çok Bölümü Çıkarma (Özyinelemeli Ayrıştırma)

Yollar veya sürüm numaraları gibi karmaşık dize yapılarını ayrıştırmak için infer'i özyinelemeli olarak kullanabilirsiniz:

// TypeScript

type SplitPath =

T extends `${infer Head}/${infer Tail}`

? [Head, ...SplitPath]

: T extends '' ? [] : [T];

type PathSegments1 = SplitPath<"api/v1/users/123">

// PathSegments1 ["api", "v1", "users", "123"] olur

type PathSegments2 = SplitPath<"product-images/large">

// PathSegments2 ["product-images", "large"] olur

type SingleSegment = SplitPath<"root">

// SingleSegment ["root"] olur

type EmptySegments = SplitPath<"">

// EmptySegments [] olur

Bu özyinelemeli koşullu tür, bir dize yolunu bölümlerinden oluşan bir demete nasıl ayrıştırabileceğinizi gösterir, bu da URL rotaları, dosya sistemi yolları veya diğer eğik çizgiyle ayrılmış tanımlayıcılar üzerinde ince taneli tür kontrolü sağlar. Bu, tür-güvenli yönlendirme sistemleri veya veri erişim katmanları oluşturmak için inanılmaz derecede kullanışlıdır.

Çıkarılan Parçaları Dönüştürme ve Yeniden Oluşturma

Ayrıca yardımcı türleri çıkarılan parçalara uygulayabilir ve yeni bir dize değişmez türü yeniden oluşturabilirsiniz:

// TypeScript

type ConvertToCamelCase =

T extends `${infer FirstPart}_${infer SecondPart}`

? `${Uncapitalize}${Capitalize}`

: Uncapitalize;

type UserDataField = ConvertToCamelCase<"user_id">

// UserDataField "userId" olur

type OrderStatusField = ConvertToCamelCase<"order_status">

// OrderStatusField "orderStatus" olur

type SingleWordField = ConvertToCamelCase<"firstName">

// SingleWordField "firstName" olur

type RawApiField =

T extends `API_${infer Method}_${infer Resource}`

? `${Lowercase}-${Lowercase}`

: never;

type GetUsersPath = RawApiField<"API_GET_USERS">

// GetUsersPath "get-users" olur

type PostProductsPath = RawApiField<"API_POST_PRODUCTS">

// PostProductsPath "post-products" olur

// type InvalidApiPath = RawApiField<"API_FETCH_DATA">; // Hata, çünkü `DATA` bir `Resource` değilse 3 parçalı yapıya tam olarak uymuyor

type InvalidApiFormat = RawApiField<"API_USERS">

// InvalidApiFormat 'never' olur (çünkü API_ sonrasında üç değil sadece iki bölüm var)

Bu, bir kurala uyan bir dizeyi (örneğin bir API'den gelen snake_case) alıp, başka bir kuraldaki (örneğin uygulamanız için camelCase) temsili için otomatik olarak bir tür oluşturabileceğinizi gösterir, hepsi derleme zamanında. Bu, harici veri yapılarını manuel tür iddiaları veya çalışma zamanı hataları olmadan dahili olanlara eşlemek için paha biçilmezdir.

Küresel Ekipler İçin En İyi Uygulamalar ve Dikkat Edilmesi Gerekenler

TypeScript'in dize işleme türleri güçlü olsa da, bunları akıllıca kullanmak esastır. İşte bunları küresel geliştirme projelerinize dahil etmek için bazı en iyi uygulamalar:

Sonuç

TypeScript'in şablon değişmez türleri, Uppercase, Lowercase, Capitalize ve Uncapitalize gibi içsel dize işleme yardımcı programlarıyla birleştiğinde, tür-güvenli dize işlemede önemli bir ilerlemeyi temsil eder. Bir zamanlar çalışma zamanı endişesi olan dize biçimlendirme ve doğrulamasını, derleme zamanı garantisine dönüştürerek kodunuzun güvenilirliğini temelden iyileştirirler.

Karmaşık, işbirlikçi projeler üzerinde çalışan küresel geliştirme ekipleri için, bu desenleri benimsemek somut ve derin faydalar sunar:

Bu güçlü özellikleri ustalaşarak, geliştiriciler daha dirençli, sürdürülebilir ve öngörülebilir uygulamalar oluşturabilirler. Dize işlemenizi yeni bir tür güvenliği ve hassasiyet düzeyine yükseltmek için TypeScript'in şablon dize desenlerini benimseyin, bu da küresel geliştirme çabalarınızın daha büyük bir güven ve verimlilikle gelişmesini sağlar. Bu, gerçekten sağlam ve küresel olarak ölçeklenebilir yazılım çözümleri oluşturmaya yönelik önemli bir adımdır.