Scoping Generics
Easy
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); // trueAfter (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