Carl Rippon

Building SPAs

Carl Rippon
BlogBooks / CoursesAbout
This site uses cookies. Click here to find out more

Generic Arrow Functions

September 02, 2020
reacttypescript

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!

Did you find this post useful?

Let me know by sharing it on Twitter.
Click here to share this post on Twitter

If you to learn more about using TypeScript with React, you may find my course useful:

Using TypeScript with React

Find out more