TypeScript types function parameters and return values, supports optional/default/rest parameters, and can type the function itself (function types) for callbacks.
function add(a: number, b: number): number { return a + b } types inputs and output; the return type is often inferred but explicit annotations lock the contract. Optional params use ? (and must follow required ones), defaults use =, and rest params use ...args: number[]. You type a callback with a function type: (value: string, index: number) => void, or type Handler = (e: Event) => void. Async functions return Promise<T>. Function overloads declare multiple signatures for one implementation. In test frameworks, precise function types make custom commands/helpers self-documenting and catch wrong-argument bugs.
A typed retry helper: function retry<T>(fn: () => Promise<T>, times: number): Promise<T> makes callers pass an async function and get back a correctly-typed promise, with wrong usages flagged.
function log(msg: string, level?: string, tag: string) — TypeScript errors. Why?