Generic Arrow Functions


In this post, we cover how arrow functions with generic parameters can be implemented. It’s not as straightforward as we might think.

Generic Arrow Functions

An example

Consider the generic arrow function below:

const firstOrNull = <T>(
arr: T[]
): T | null =>
arr.length === 0 ? null : arr[0];

This is a strongly-typed function that returns the first item in an array or null if it is empty.

This code is problematic though:

Arrow function errors

If we look at the transpiled code, we get a clue as to what the problem is:

Transpiled arrow function

The angle brackets are being confused with a JSX element!

Extends trick

In order to resolve the error, we need to help the transpilation process treat angle brackets as generic parameters. One way to do this is to add a constraint:

const firstOrNull = <T extends unknown>(
arr: T[]
): T | null =>
arr.length === 0 ? null : arr[0];

We extend from unknown because every type is assignable to unknown. The any type could also be used, but this isn’t type-safe.

Comma trick

Another trick is to add a comma after the generic parameter:

const firstOrNull = <T,>(
arr: T[]
): T | null =>
arr.length === 0 ? null : arr[0];

This is the syntax for defining multiple parameters and doesn’t error, even though we haven’t defined two parameters. This is enough for the transpilation process to treat the angle brackets as generic parameters.

Just use a regular function

Arguably the simplest solution is to use a regular function as opposed to an arrow function:

function firstOrNull<T>(arr: T[]): T | null {
return arr.length === 0 ? null : arr[0];
}

It works like a treat and no tricks!

Learn React with TypeScript - 3rd Edition

New

A comprehensive guide to building modern React applications with TypeScript. Learn best practices, advanced patterns, and real-world development techniques.

View on Amazon
Learn React with TypeScript - Third Edition