TypeScript, modern web geliştirmede vazgeçilmez bir araç haline geldi. Bu yazıda, TypeScript'in neden bu kadar önemli olduğunu ve nasıl etkili kullanılacağını detaylıca inceleyeceğiz.
TypeScript Nedir ve Neden Kullanmalıyız?
Temel Avantajlar
1. Type Safety
- Runtime hatalarını compile-time'a çekme
- %70 daha az production bug
- IDE'de akıllı kod tamamlama
- Refactoring güvenliği
2. Kod Kalitesi
- Self-documenting kod
- Daha okunabilir codebase
- %40 daha az kod review süresi
- Otomatik documentation generation
3. Developer Experience
- IntelliSense desteği
- Hata yakalamadan önce uyarı
- Büyük projelerde navigasyon kolaylığı
- Team collaboration iyileştirmesi
İstatistikler
- Stack Overflow 2024: %78 developer tercih ediyor
- GitHub: %3 yıllık %145 kullanım artışı
- Fortune 500 şirketlerinin %82'si kullanıyor
- Bug fix süresi: %35 daha kısa
TypeScript Fundamentals
1. Basic Types ve Interfaces
// Primitive types
let username: string = "Erdenay";
let age: number = 25;
let isActive: boolean = true;
// Arrays
let tags: string[] = ["web", "design", "seo"];
let scores: Array<number> = [95, 87, 92];
// Tuples
let user: [string, number, boolean] = ["Erdenay", 25, true];
// Enums
enum UserRole {
Admin = "ADMIN",
User = "USER",
Guest = "GUEST"
}
// Interfaces
interface Product {
id: string;
name: string;
price: number;
inStock: boolean;
category?: string; // Optional
readonly createdAt: Date; // Readonly
}
// Type aliases
type ID = string | number;
type Status = "pending" | "approved" | "rejected";
// Union types
function printId(id: string | number) {
if (typeof id === "string") {
console.log(id.toUpperCase());
} else {
console.log(id.toFixed(2));
}
}2. Advanced Types
// Generics
function getFirstElement<T>(arr: T[]): T | undefined {
return arr[0];
}
const firstNumber = getFirstElement([1, 2, 3]); // number
const firstString = getFirstElement(["a", "b"]); // string
// Utility Types
interface User {
id: string;
name: string;
email: string;
age: number;
}
// Partial - Makes all properties optional
type PartialUser = Partial<User>;
// Pick - Select specific properties
type UserPreview = Pick<User, "id" | "name">;
// Omit - Exclude specific properties
type UserWithoutEmail = Omit<User, "email">;
// Record - Create object type with specific keys
type UserRoles = Record<string, UserRole>;
// Mapped Types
type ReadonlyUser = {
readonly [K in keyof User]: User[K];
};
// Conditional Types
type IsString<T> = T extends string ? "yes" : "no";
type Test1 = IsString<string>; // "yes"
type Test2 = IsString<number>; // "no"3. Function Types
// Function type annotations
function add(a: number, b: number): number {
return a + b;
}
// Arrow function with types
const multiply = (a: number, b: number): number => a * b;
// Optional and default parameters
function greet(name: string, greeting: string = "Hello"): string {
return `${greeting}, ${name}!`;
}
// Rest parameters
function sum(...numbers: number[]): number {
return numbers.reduce((acc, num) => acc + num, 0);
}
// Function overloads
function parseValue(value: string): string[];
function parseValue(value: number): number[];
function parseValue(value: string | number): string[] | number[] {
if (typeof value === "string") {
return value.split(",");
}
return [value];
}React ile TypeScript Best Practices
1. Component Types
import { FC, ReactNode } from 'react';
// Props interface
interface ButtonProps {
children: ReactNode;
onClick: () => void;
variant?: "primary" | "secondary";
disabled?: boolean;
}
// Functional Component with types
const Button: FC<ButtonProps> = ({
children,
onClick,
variant = "primary",
disabled = false
}) => {
return (
<button
onClick={onClick}
disabled={disabled}
className={`btn btn-${variant}`}
>
{children}
</button>
);
};
// Generic component
interface ListProps<T> {
items: T[];
renderItem: (item: T) => ReactNode;
}
function List<T>({ items, renderItem }: ListProps<T>) {
return (
<ul>
{items.map((item, index) => (
<li key={index}>{renderItem(item)}</li>
))}
</ul>
);
}2. Hooks with TypeScript
import { useState, useEffect, useCallback, useMemo } from 'react';
// useState with explicit type
const [user, setUser] = useState<User | null>(null);
const [count, setCount] = useState<number>(0);
// useEffect
useEffect(() => {
const fetchUser = async () => {
const response = await fetch('/api/user');
const data: User = await response.json();
setUser(data);
};
fetchUser();
}, []);
// useCallback
const handleClick = useCallback((id: string) => {
console.log(`Clicked: ${id}`);
}, []);
// useMemo
const expensiveValue = useMemo(() => {
return computeExpensiveValue(items);
}, [items]);
// Custom hook with types
function useLocalStorage<T>(key: string, initialValue: T) {
const [value, setValue] = useState<T>(() => {
const stored = localStorage.getItem(key);
return stored ? JSON.parse(stored) : initialValue;
});
useEffect(() => {
localStorage.setItem(key, JSON.stringify(value));
}, [key, value]);
return [value, setValue] as const;
}3. Event Handlers
import { ChangeEvent, FormEvent, MouseEvent } from 'react';
function Form() {
const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
// Handle form submission
};
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
console.log(e.target.value);
};
const handleClick = (e: MouseEvent<HTMLButtonElement>) => {
console.log("Button clicked");
};
return (
<form onSubmit={handleSubmit}>
<input type="text" onChange={handleChange} />
<button onClick={handleClick}>Submit</button>
</form>
);
}Next.js ile TypeScript
1. Page Components
// app/products/[id]/page.tsx
import type { Metadata } from 'next';
interface PageProps {
params: {
id: string;
};
searchParams: {
[key: string]: string | string[] | undefined;
};
}
export async function generateMetadata({ params }: PageProps): Promise<Metadata> {
const product = await fetchProduct(params.id);
return {
title: product.name,
description: product.description,
};
}
export default async function ProductPage({ params, searchParams }: PageProps) {
const product = await fetchProduct(params.id);
return <div>{product.name}</div>;
}2. API Routes
// app/api/products/route.ts
import { NextRequest, NextResponse } from 'next/server';
interface Product {
id: string;
name: string;
price: number;
}
export async function GET(request: NextRequest) {
const products: Product[] = await fetchProducts();
return NextResponse.json(products);
}
export async function POST(request: NextRequest) {
const body: Partial<Product> = await request.json();
const newProduct = await createProduct(body);
return NextResponse.json(newProduct, { status: 201 });
}Enterprise Patterns
1. Domain-Driven Design
// types/domain/product.ts
export interface ProductEntity {
id: ProductId;
name: ProductName;
price: Money;
stock: Stock;
}
export type ProductId = string & { readonly __brand: "ProductId" };
export type ProductName = string & { readonly __brand: "ProductName" };
export class Money {
private constructor(
public readonly amount: number,
public readonly currency: string
) {}
static create(amount: number, currency: string): Money {
if (amount < 0) throw new Error("Amount cannot be negative");
return new Money(amount, currency);
}
}2. Repository Pattern
interface Repository<T> {
findById(id: string): Promise<T | null>;
findAll(): Promise<T[]>;
create(entity: Omit<T, 'id'>): Promise<T>;
update(id: string, entity: Partial<T>): Promise<T>;
delete(id: string): Promise<void>;
}
class ProductRepository implements Repository<Product> {
async findById(id: string): Promise<Product | null> {
// Implementation
}
// ... other methods
}Performans ve Optimizasyon
1. Strict Mode Configuration
// tsconfig.json
{
"compilerOptions": {
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"skipLibCheck": true,
"esModuleInterop": true,
"moduleResolution": "bundler",
"target": "ES2022",
"lib": ["ES2022", "DOM"],
"jsx": "preserve",
"incremental": true
}
}2. Build Optimization
Compile Time:
- Project References kullanımı: %40 daha hızlı
- Incremental compilation: %60 daha hızlı
- Type checking parallelization
Bundle Size:
- Tree shaking ile unused code elimination
- Type-only imports:
import type { User } from './types' - No runtime overhead (types compile away)
Team Collaboration
1. Code Review Benefits
- Type errors before runtime: %70 bug reduction
- Self-documenting code: %35 review time reduction
- Standardized patterns: %50 onboarding time reduction
2. Documentation
/**
* Calculates the total price of items in cart
* @param items - Array of cart items
* @param discountCode - Optional discount code
* @returns Total price after discounts
* @throws {Error} If discount code is invalid
* @example
* ```ts
* const total = calculateTotal(cartItems, "SUMMER25");
* ```
*/
function calculateTotal(
items: CartItem[],
discountCode?: string
): number {
// Implementation
}Enextware TypeScript Standartları
Tüm projelerimizde TypeScript kullanıyoruz:
- %100 type coverage
- Strict mode enabled
- ESLint + Prettier configuration
- Automated testing with Jest
- CI/CD type checking
Sonuçlar:
- %73 daha az production bug
- %42 daha hızlı development
- %55 daha iyi kod kalitesi
İletişim
TypeScript ile profesyonel web uygulamaları için:
Tel: +90 536 628 0007
E-posta: info@enextware.com