TypeScript function types

Kenny DuMez
Kenny DuMez
Graphite software engineer

One of the core features of TypeScript is its ability to define types for functions, making code more predictable and easier to maintain. This guide will explore how to work with function types in TypeScript, including defining function types, specifying return types, and using arrow functions and async functions.

In TypeScript, you can define the types of parameters and the return type of a function. Here is a simple example:

Terminal
function add(a: number, b: number): number {
return a + b
}

In this example, add is a function that takes two parameters, a and b, both of type number, and returns a number.

You can explicitly define the type of a function using a type alias. This is useful when you want to reuse the function type in multiple places:

Terminal
type BinaryOperation = (a: number, b: number) => number
const add: BinaryOperation = (a, b) => a + b
const subtract: BinaryOperation = (a, b) => a - b

Here, BinaryOperation is a type alias for a function type that takes two number arguments and returns a number.

It's good practice to explicitly specify the return type of a function. TypeScript can infer the return type, but explicitly stating it makes your code clearer and helps catch errors early:

Terminal
function multiply(a: number, b: number): number {
return a * b
}

In this example, the function multiply explicitly specifies that it returns a number.

If a function does not return a value, you can use the void type:

Terminal
function logMessage(message: string): void {
console.log(message)
}

Here, logMessage takes a string argument and returns void, indicating that it does not return any value.

TypeScript allows you to define optional parameters and default values for function parameters:

Terminal
function greet(name: string, greeting: string = 'Hello'): void {
console.log(`${greeting}, ${name}!`)
}
greet('Alice')
greet('Bob', 'Hi')

In this example, greeting is an optional parameter with a default value of "Hello".

Arrow functions in TypeScript can also have their types defined. Here's an example of an arrow function with a specified return type:

Terminal
const divide: (a: number, b: number) => number = (a, b) => {
if (b === 0) {
throw new Error('Division by zero')
}
return a / b
}

This defines an arrow function divide that takes two number arguments and returns a number.

You can also define function types using interfaces. This is useful when working with objects that have distinct methods:

Terminal
interface Comparator {
(a: number, b: number): number
}
const compare: Comparator = (a, b) => {
return a - b
}

Here, Comparator is an interface representing a function type, and compare is a function that adheres to this interface.

Asynchronous functions return a Promise, and you can specify the type of the resolved value:

Terminal
async function fetchData(url: string): Promise<string> {
const response = await fetch(url)
const data = await response.text()
return data
}

In this example, fetchData is an async function that takes a string argument and returns a Promise<string>.

Higher-order functions are functions that take other functions as arguments or return functions as their result. Here’s an example of a higher-order function with types:

Terminal
function applyOperation(
a: number,
b: number,
operation: (x: number, y: number) => number
): number {
return operation(a, b)
}
const result = applyOperation(5, 3, (x, y) => x * y)
console.log(result) // 15

In this example, applyOperation takes two number arguments and a function operation that operates on two number arguments and returns a number.

Generic functions allow you to write flexible, reusable functions that work with any type. Here's an example of a generic function:

Terminal
function identity<T>(arg: T): T {
return arg
}
const num = identity<number>(42)
const str = identity<string>('Hello')

In this example, identity is a generic function that takes an argument of type T and returns a value of the same type T.

For more information on function typing in TypeScript, see the official TypeScript documentation.

Graphite
Git stacked on GitHub

Stacked pull requests are easier to read, easier to write, and easier to manage.
Teams that stack ship better software, faster.

Or install our CLI.
Product Screenshot 1
Product Screenshot 2