TypeScript Functions

Functions & Narrowing

Typing function inputs and outputs is where TypeScript earns its keep. Narrowing then lets the compiler track a value's type as it flows through your code.

TypeScript 5 Interview Key 3 Topics
01

Typed Functions

Annotate each parameter's type; the return type is usually inferred. Parameters can be optional (?), have defaults, or gather the rest into a typed array.

TypeScript — Parameters & Returns
// typed params, inferred return (number)
function add(a: number, b: number) {
  return a + b;
}

// explicit return type
function greet(name: string): string {
  return `Hi, ${name}`;
}

// optional (?), default, and rest params
function log(msg: string, level: string = "info", ...tags: string[]) {
  console.log(level, msg, tags);
}
log("started");                    // level defaults to "info"
log("failed", "error", "auth", "db");

// function type as a variable
const multiply: (a: number, b: number) => number = (a, b) => a * b;
An optional parameter x?: number has type number | undefined. It must come after all required parameters, and you must handle the undefined case inside the function.
02

Function Overloads

Overload signatures let one function present different typed shapes to callers, so the return type depends on the arguments. You declare the signatures, then write one implementation that covers them all.

TypeScript — Overloads
// overload signatures — what callers see
function parse(x: string): string[];
function parse(x: number): number;
// implementation signature — not visible to callers
function parse(x: string | number): string[] | number {
  return typeof x === "string" ? x.split("") : x * 2;
}

const a = parse("hi");   // typed as string[]
const b = parse(10);     // typed as number
Often a union type or generics is cleaner than overloads. Reach for overloads when the return type genuinely changes shape based on the input type, as above.
03

Narrowing & Type Guards

Narrowing is how TypeScript refines a broad type to a specific one inside a branch. The compiler tracks the checks you write and updates the type accordingly.

TypeScript — Narrowing
function format(x: string | number) {
  // typeof guard
  if (typeof x === "string") {
    return x.toUpperCase();   // x is string here
  }
  return x.toFixed(2);       // x is number here
}

// truthiness, instanceof, and 'in' also narrow
if (obj instanceof Date) obj.getTime();
if ("name" in user) user.name;

// custom type guard: `arg is Type`
function isString(v: unknown): v is string {
  return typeof v === "string";
}
if (isString(input)) input.trim();   // input narrowed to string
A custom type guard (return type v is string) teaches the compiler how to narrow a value. It's the key to safely working with unknown and discriminated unions.

Quick Quiz

1. An optional parameter x?: number has type…
2. Optional parameters must appear…
3. A custom type guard has return type…
4. Inside if (typeof x === "string"), x is narrowed to…
5. Function overloads let the return type…