Skip to content

Functions in TypeScript

Functions are the building blocks of any programming language, and TypeScript is no exception. In this section, we will explore how to define and use functions in TypeScript, including how to specify parameter types, return types, optional parameters, default parameters, rest parameters, and special return types like void and never. By the end of this section, you will have a solid understanding of how to work with functions in TypeScript and how to leverage its type system to write safer and more maintainable code.

In TypeScript, you can tell a function what types of values it should receive and what type of value it should return. This helps catch mistakes before your code even runs.

function add(a: number, b: number): number {
return a + b;
}
  • a: number, b: number - these tell TypeScript that both inputs must be numbers.
  • : number after the ) - this tells TypeScript that the function must return a number.

If you try to pass a string or return a string from this function, TypeScript will give you an error right away.

Here is how TypeScript checks a function from start to finish:

graph TD A[Input Parameters] --> B[Type Check] B --> C[Function Body] C --> D[Return Value] D --> E[Return Type Check]

TypeScript checks the inputs when you call the function, and checks the return value when the function is done. Both checks happen automatically.

Sometimes a function has a parameter that is not always needed. You can mark it as optional using ?. This means the caller does not have to provide that value.

function greet(name: string, age?: number): string {
return age ? `${name} (${age})` : name;
}

Rules:

  • Optional parameters use ? after the name
  • Optional parameters must come at the end, after all required parameters
  • Inside the function, an optional parameter like age is treated as number | undefined - meaning it might be a number, or it might not have been passed at all

You can give a parameter a default value. If the caller does not pass that argument, TypeScript will use the default value instead. This avoids having to manually check for undefined inside the function.

function createUser(name: string, role: string = "user") {
return { name, role };
}

Here, if you call createUser("Sahil") without a role, role will automatically be "user".

Rest parameters let a function accept any number of values for a single parameter. All the values get collected into one array. This is useful when you do not know in advance how many arguments will be passed.

function sum(...numbers: number[]): number {
return numbers.reduce((acc, n) => acc + n, 0);
}

You can call this as sum(1, 2, 3) or sum(10, 20) or even sum(5) - any number of arguments works, and TypeScript makes sure they are all numbers.

These two return types describe functions that do not return a normal value.

void

The function finishes running but does not return any useful value. Think of it as “this function does something but gives nothing back.”

never

The function never finishes normally - it either throws an error or runs forever.

function logMessage(message: string): void {
console.log(message);
}
function fail(message: string): never {
throw new Error(message);
}

Use never for:

  • functions that always throw an error
  • functions with infinite loops that never stop
  • exhaustive checks in union types (making sure every possible case is handled)

In JavaScript and TypeScript, functions can be stored in variables, passed to other functions, or returned from functions. You can give a function stored in a variable its own type using a type alias.

type MathOp = (a: number, b: number) => number;
const multiply: MathOp = (a, b) => a * b;

This pattern is very common when passing functions as callbacks (a function you pass to another function to be called later) or when using dependency injection (passing a function in so it can be swapped out later).