TypeScript Arrow Functions with Generics: Complete Guide with Examples

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Less Code, More Value: Understanding Arrow Functions and Generics in TypeScript



Have you ever written a small utility in TypeScript that needed to work with numbers, strings, and arrays? And immediately ran into the problem: how to make the data type flexible without TypeScript complaining? The answer is generics. And if you love concise syntax, you're probably already using arrow functions.



But here's the catch: on Stack Overflow, the question "What is the syntax for Typescript arrow functions with generics?" has thousands of views. It turns out that even experienced developers sometimes get confused with this seemingly simple combination. In this article, we'll break down how to properly write TypeScript arrow functions with generics, look at common mistakes, and show you how to make your code cleaner and safer.



Ready? Let's go!



What Are Generics in Arrow Functions?



First, a quick primer. Generics allow you to create components (functions, classes, interfaces) that work with different types rather than a single specific one. Instead of writing separate functions for numbers and strings, you write one — with a generic.



Arrow functions are a compact function syntax in JavaScript and TypeScript. When you combine them with generics, you get a powerful tool for creating reusable utilities.



// Regular function with genericsfunction identity<T>(arg: T): T {    return arg;}

// Arrow function with generics — what does it look like?const arrowIdentity = <T>(arg: T): T => arg;


Simple, right? Yes, but there are nuances we'll cover below.



Basic Syntax: How to Properly Declare a TypeScript Arrow Function with Generics



The simplest and most common way is to place the type parameter (generic) before the parentheses with arguments:



const firstElement = <T>(arr: T[]): T | undefined => {    return arr[0];};

// Usageconst num = firstElement([1, 2, 3]); // type: number | undefinedconst str = firstElement(['a', 'b']); // type: string | undefined


Here, <T> is the generic declaration. TypeScript will automatically infer the type of T based on the passed argument. If you want to explicitly specify the type, that works too:



const num = firstElement<number>([1, 2, 3]); // Explicitly specifying the type


Important: In JSX (React), this syntax can conflict with markup. There are workarounds for such cases (covered below).



Multiple Generics in a Single Arrow Function



You can use multiple type parameters:



const pair = <T, U>(first: T, second: U): [T, U] => {    return [first, second];};

const result = pair(42, 'hello'); // type: [number, string]


This is especially useful when working with utilities like map, reduce, or when creating wrappers.



JSX (React) Issues and Their Solutions



If you're writing React with TypeScript, you'll notice that the <T>(arg) syntax can be interpreted by the compiler as a JSX tag. This is the classic problem that made the Stack Overflow question so popular.



There are two main solutions:



1. Use extends (even if not needed)



Add extends unknown or extends Record<string, never>:



const myFunction = <T extends unknown>(arg: T): T => {    return arg;};


This explicitly tells TypeScript that <T> is a generic, not JSX.



2. Use the comma syntax



In some cases, adding a comma after the generic helps:



const myFunction = <T,>(arg: T):                

Blogs

Book Recommendations