← Back to TypeScript Menu | 🏠 Hub
// Parameter types + return type
function add(a: number, b: number): number {
return a + b;
}
// Arrow function
const multiply = (a: number, b: number): number => a * b;
// Void — no return value
function log(message: string): void {
console.log(message);
}
// Never — never returns (throws or infinite loop)
function throwError(msg: string): never {
throw new Error(msg);
}
// Optional parameters
function greet(name: string, greeting?: string): string {
return `${greeting ?? "Hello"}, ${name}!`;
}
greet("Ko"); // "Hello, Ko!"
greet("Ko", "Hi"); // "Hi, Ko!"
// Default parameters
function createUser(name: string, role: string = "user", active: boolean = true) {
return { name, role, active };
}
// Rest parameters
function sum(...numbers: number[]): number {
return numbers.reduce((total, n) => total + n, 0);
}
sum(1, 2, 3, 4, 5); // 15
// Function type annotation
type Transformer = (input: string) => string;
type Calculator = (a: number, b: number) => number;
type Callback = (err: Error | null, data: string) => void;
// Higher-order functions
function applyTransform(text: string, fn: Transformer): string {
return fn(text);
}
const upper: Transformer = (s) => s.toUpperCase();
const trim: Transformer = (s) => s.trim();
applyTransform(" hello ", trim); // "hello"
applyTransform("hello", upper); // "HELLO"
// Array higher-order with types
function filterUsers<T extends { active: boolean }>(items: T[], active: boolean): T[] {
return items.filter(item => item.active === active);
}
// Event handler types
type EventHandler<T = Event> = (event: T) => void;
const handleClick: EventHandler<MouseEvent> = (e) => {
console.log(e.clientX, e.clientY);
};
// Function overloads — same function, different signatures
function format(value: string): string;
function format(value: number): string;
function format(value: Date): string;
// Implementation (must handle all cases)
function format(value: string | number | Date): string {
if (typeof value === "string") return value.trim();
if (typeof value === "number") return value.toFixed(2);
return value.toISOString().split("T")[0];
}
format(" hello "); // "hello"
format(3.14159); // "3.14"
format(new Date()); // "2024-01-15"
// API request with overloads
interface User { id: number; name: string; }
interface Post { id: number; title: string; }
function fetchData(endpoint: "/users"): Promise<User[]>;
function fetchData(endpoint: "/posts"): Promise<Post[]>;
function fetchData(endpoint: string): Promise<unknown> {
return fetch(endpoint).then(r => r.json());
}
const users = await fetchData("/users"); // type: User[]
const posts = await fetchData("/posts"); // type: Post[]
// async function always returns Promise<T>
async function getUser(id: number): Promise<User | null> {
const res = await fetch(`/api/users/${id}`);
if (!res.ok) return null;
return res.json() as Promise<User>;
}
// Error-safe fetch wrapper
async function safeFetch<T>(url: string): Promise<{ data: T | null; error: string | null }> {
try {
const res = await fetch(url);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data: T = await res.json();
return { data, error: null };
} catch (err) {
const msg = err instanceof Error ? err.message : "Unknown error";
return { data: null, error: msg };
}
}
// Usage
const { data: users, error } = await safeFetch<User[]>("/api/users");
// Typed API service
interface ApiResponse<T> {
data: T;
meta: { total: number; page: number };
}
async function getUsers(page = 1): Promise<ApiResponse<User[]>> {
const res = await fetch(`/api/users?page=${page}`);
return res.json();
}
← TS 02 | Next: TS 04 → Classes →