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.
Type-safe mimari, Zod entegrasyonu ve TS kod review için iletişime geçin