Scoping Generics

EasyVeeam

Prompt

How to scope the type of generic to string | number here?

type FooFunc = <B>(bar: B) => B;

let f: FooFunc = (bar) => bar;
let response = f(true);
console.log(response);

Solution

In TypeScript generics, extends is used to create a constraint. It tells the compiler that the generic type B must be a type that is assignable to string|number. It essentially limits the set of types that can be used for B.

By adding extends string|number, you are changing the signature from a function that accepts any type B and returns the same type B to a function that accepts any type B as long as it's a string or a number, and returns that same type.

type FooFunc = <B extends string | number>(bar: B) => B;

let f: FooFunc = (bar) => bar;
let response = f(true);
console.log(response);

Code Example

Before (No Constraint)

Without the constraint, any type is allowed, including boolean.

type FooFunc = <B>(bar: B) => B;

let f: FooFunc = (bar) => bar;
let response = f(true); // ✅ No error, 'response' is of type 'boolean'
console.log(response); // true

After (With Constraint)

With the extends string|number constraint, passing a boolean will now result in a type error.

type FooFunc = <B extends string | number>(bar: B) => B;

let f: FooFunc = (bar) => bar;

// --- Valid Calls ---
let stringResponse = f('hello'); // OK, 'stringResponse' is type 'string'
let numberResponse = f(123); // OK, 'numberResponse' is type 'number'

// --- Invalid Call ---
let booleanResponse = f(true); // ❌ Error: Argument of type 'boolean' is not
// assignable to parameter of type 'string | number'.
00:00