Generic arrow functions in TypeScript

In TypeScript, generics allow developers to write flexible and reusable components while still maintaining type safety. Combined with arrow functions, you can create concise, type-safe utility functions and callbacks. In this guide, we'll explore how to use generic arrow functions in TypeScript.

Basics of TypeScript Generics

Generics in TypeScript provide a way to create reusable components that work over a variety of types rather than a single one.

function identity<T>(arg: T): T { return arg; }

In this example, the function identity has a single type parameter T. This means it can be called with any type and will return a value of that same type.

Arrow Functions in TypeScript

Arrow functions provide a concise syntax to represent anonymous functions. Here's the basic syntax:

const functionName = (parameter1, parameter2) => { // function body }

Combining Generics with Arrow Functions

Now, let's combine both concepts. Here's how you can write a generic arrow function:

const identity = <T>(arg: T): T => { return arg; }

This is essentially the same identity function we looked at earlier but written as an arrow function.

Examples

  1. Swapping Tuple Values

    Suppose you want to write a type-safe function to swap the values in a 2-tuple. Here's how you can do it using a generic arrow function:

    const swap = <T, U>(tuple: [T, U]): [U, T] => { return [tuple[1], tuple[0]]; } console.log(swap([1, 'one'])); // Outputs: ['one', 1]
  2. Mapping Array Values

    Consider a function that maps over an array and returns the results. Here's a generic version of it:

    const mapArray = <T, U>(arr: T[], transform: (value: T) => U): U[] => { return arr.map(transform); } const numbers = [1, 2, 3]; const strings = mapArray(numbers, (num) => num.toString()); console.log(strings); // Outputs: ['1', '2', '3']

Type Constraints with Generic Arrow Functions

Sometimes, you might want to limit the types that can be passed to a generic function. This is achieved using type constraints.

For instance, suppose you want to ensure that the type has a .length property:

const getLength = <T extends { length: number }>(arg: T): number => { return arg.length; } console.log(getLength("hello")); // Outputs: 5 console.log(getLength([1, 2, 3])); // Outputs: 3

You wouldn't be able to call getLength with a number or boolean, since they don't have a .length property.

Invite only

We're building the next generation of data visualization.