TypeScript''i sadece interface ve type alias yazmak için kullanıyorsanız potansiyelin %20''sindesiniz. Generics, utility types ve conditional types ile derleyiciden karmaşık iş mantığını kontrol ettirebilir, runtime hatalarını derleme zamanında yakalayabilirsiniz. Bu yazı TypeScript''in gerçek gücünü açığa çıkarır.

Generics

İlgili rehberler: Yazılım geliştirme süreçleri · PostgreSQL optimizasyonu · Git ileri seviye komutlar · Redis nedir, nasıl kullanılır · Docker ile deploy

Fonksiyon veya type''ın tipini çağrı zamanında belirlemek. Kod tekrar kullanımı + tip güvenliği birlikte.

// Basit generic
function identity<T>(value: T): T {
    return value;
}
identity<number>(42);         // T = number
identity('hello');            // T = string (inference)

// Generic constraint
function getLength<T extends { length: number }>(x: T): number {
    return x.length;
}
getLength('str');     // OK
getLength([1, 2, 3]); // OK
getLength(42);        // ERROR

// Multiple type params
function pair<K, V>(key: K, value: V): [K, V] {
    return [key, value];
}
const p = pair('age', 30);    // [string, number]

Built-in Utility Types

interface User {
    id: number;
    name: string;
    email: string;
    password: string;
    createdAt: Date;
}

// Partial — tüm field'lar optional
type UserUpdate = Partial<User>;
// { id?: number; name?: string; ... }

// Required — tüm field'lar required
type StrictUser = Required<UserUpdate>;

// Pick — belirli field'ları seç
type UserPublic = Pick<User, 'id' | 'name' | 'email'>;

// Omit — belirli field'ları at
type UserSafe = Omit<User, 'password'>;

// Readonly
type Frozen = Readonly<User>;

// Record — key-value type
type UsersMap = Record<string, User>;
const users: UsersMap = { 'u1': { ... }, 'u2': { ... } };

ReturnType, Parameters, Awaited

function createUser(data: { name: string; email: string }): Promise<User> { ... }

type CreateUserParams = Parameters<typeof createUser>[0];
// { name: string; email: string }

type CreateUserResult = ReturnType<typeof createUser>;
// Promise<User>

type CreateUserResolved = Awaited<CreateUserResult>;
// User

// API response tip'ini otomatik çıkar
type ApiUser = Awaited<ReturnType<typeof createUser>>;

Conditional Types

// T extends U ? X : Y
type IsString<T> = T extends string ? true : false;
type A = IsString<'hello'>;  // true
type B = IsString<42>;       // false

// Distributive conditional types (union üstünde distribute olur)
type NonNull<T> = T extends null | undefined ? never : T;
type Result = NonNull<string | null | number>;  // string | number

// Gerçek dünya: nullable field'ları çıkar
type NonNullableKeys<T> = {
    [K in keyof T]-?: T[K] extends null | undefined ? never : K
}[keyof T];

infer Keyword

// Array element type'ını çıkar
type ElementType<T> = T extends (infer U)[] ? U : never;
type A = ElementType<string[]>;     // string
type B = ElementType<number[][]>;   // number[]

// Function return type'ını çıkar
type MyReturn<T> = T extends (...args: any[]) => infer R ? R : never;

// Promise unwrap
type Unwrap<T> = T extends Promise<infer U> ? U : T;

// Template literal'den tip çıkar
type GetFirstWord<S> = S extends `${infer First} ${string}` ? First : S;
type W = GetFirstWord<'Hello World'>;  // 'Hello'

Mapped Types

// Interface'i tümüyle dönüştür
type Getters<T> = {
    [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};

interface User { name: string; age: number; }
type UserGetters = Getters<User>;
// { getName: () => string; getAge: () => number }

// Nullable yap
type Nullable<T> = { [K in keyof T]: T[K] | null };

// Deep partial
type DeepPartial<T> = {
    [K in keyof T]?: T[K] extends object ? DeepPartial<T[K]> : T[K];
};

Template Literal Types

type EventName = `on${Capitalize<'click' | 'change' | 'hover'>}`;
// 'onClick' | 'onChange' | 'onHover'

type Endpoint = `/${'api' | 'admin'}/${'users' | 'posts'}/:id`;
// '/api/users/:id' | '/api/posts/:id' | '/admin/users/:id' | '/admin/posts/:id'

// HTTP method + path dar tip
type Route =
    | `GET /${string}`
    | `POST /${string}`
    | `DELETE /${string}`;
const r: Route = 'GET /users';   // OK
const w: Route = 'PATCH /users'; // ERROR

Discriminated Unions

type ApiResponse<T> =
    | { status: 'success'; data: T }
    | { status: 'error'; error: string }
    | { status: 'loading' };

function render<T>(res: ApiResponse<T>) {
    switch (res.status) {
        case 'success': return res.data;       // T
        case 'error':   return res.error;      // string
        case 'loading': return 'Loading...';
    }
}
// TypeScript exhaustiveness check yapar — case atlayınca uyarır

Type Guards

// Custom type guard
function isUser(x: unknown): x is User {
    return typeof x === 'object' && x !== null
        && 'id' in x && typeof x.id === 'number'
        && 'email' in x;
}

// Kullanım
const data: unknown = fetchData();
if (isUser(data)) {
    data.email;  // TS artık User biliyor
}

// Zod ile runtime + type (endüstri standardı)
import { z } from 'zod';
const UserSchema = z.object({
    id: z.number(),
    email: z.string().email(),
    age: z.number().min(0).max(150)
});
type User = z.infer<typeof UserSchema>;  // tip otomatik üretilir

satisfies Operator

// 4.9+ satisfies: tip uyumluluğunu kontrol et, ama literal tipleri kaybetme
const config = {
    debug: false,
    port: 3000,
    env: 'production'
} satisfies { debug: boolean; port: number; env: 'development' | 'production' };

config.env;  // 'production' (literal) — 'as' kullanılsa string olurdu

Pratik: Type-Safe Event Emitter

type EventMap = {
    'user:created': { id: string; email: string };
    'user:deleted': { id: string };
    'error': Error;
};

class TypedEmitter<T> {
    on<K extends keyof T>(event: K, listener: (data: T[K]) => void) { ... }
    emit<K extends keyof T>(event: K, data: T[K]) { ... }
}

const bus = new TypedEmitter<EventMap>();
bus.on('user:created', data => data.email);  // OK, data: { id, email }
bus.emit('user:deleted', { id: '42' });      // OK
bus.emit('user:deleted', { email: 'x' });    // ERROR — id eksik

Modern Yazılım Geliştirme ve DevOps Pratikleri

Profesyonel yazılım geliştirme süreci üç pillar üzerine kuruludur: kaynak kontrolü (Git + GitHub/GitLab pull request akışı, code review zorunlu), CI/CD pipeline (otomatik test + lint + build + deploy), ve gözlemlenebilirlik (Sentry/Datadog/Grafana ile log, metric, trace toplama). Test piramidi (unit > integration > e2e) ile kod kalitesini garantilemek, mikroservis mimarisinde Docker container ve Kubernetes orkestrasyonu kullanmak, REST veya GraphQL API tasarımında OpenAPI/GraphQL Schema sözleşmesi tutmak modern standardlardır. Yazılım geliştirme yaşam döngüsü boyunca (gereksinim → tasarım → implementasyon → test → deploy → bakım) Agile/Scrum sprintleri 1-2 hafta, DevOps takımları sürekli teslim (continuous delivery) prensibiyle çalışır.

TypeScript eğitim ve danışmanlık

Type-safe mimari, Zod entegrasyonu ve TS kod review için iletişime geçin

WhatsApp