Mastering TypeScript Generics: From Arrays to Arrow Functions with Type Safety
Mastering Generics with Arrays and Arrow Functions in TypeScript
Example 1: Generics in Arrays
// Without Generics
function getFirstItem(arr: (string | number)[]): (string | number) {
return arr[0];
}
let arr1 = getFirstItem([1, 2, 3]); // 1
let arr2 = getFirstItem(['one', 'two']); // 'one'
let str = arr2.toLowerCase(); // Error: Property 'toLowerCase' does not exist on type 'string | number'.
Solution using Generics:
function getFirstItem<Type>(arr: Type[]): Type {
return arr[0];
}
let arr1 = getFirstItem([1, 2, 3]); // 1
let arr2 = getFirstItem(['one', 'two']); // 'one'
let str = arr2.toUpperCase(); // 'ONE'
Now, with generics, TypeScript infers the type correctly, allowing operations like toUpperCase()
on strings.
Example 2: Using Arrow Functions
const getFirstItem = <Type, >(arr: Type[]): Type => {
return arr[0];
}
let arr1 = getFirstItem([1, 2, 3]); // 1
The use of generics with arrow functions is concise and maintains type safety.
The ,
in <Type,>
denotes that this is not JSX syntax but rather a generic type parameter.
Generics provide a flexible and powerful way to work with different data types while maintaining type safety in TypeScript.
Unlocking Type Safety with Generic Constraints in TypeScript
Example 1: Type Parameter Constraints
function printName<Type extends { name: string }>(obj: Type): void {
console.log(obj.name);
}
printName({ name: "John" }); // Valid
// printName({ age: 25 }); // Error: Type '{ age: number }' is not assignable to a parameter of type '{ name: string }'.
Explanation:
The generic function
printName
has a type parameterType
with a constraint{ name: string }
.This ensures that any object passed to
printName
must have aname
property of type string.Calling
printName({ name: "John" })
is valid, but attempting to pass an object without aname
property results in a compile-time error.
Example 2: Multiple Type Parameters with Constraints
function display<T, U extends number>(valOne: T, valTwo: U): object {
return { valOne, valTwo };
}
display(3, 2); // { valOne: 3, valTwo: 2 }
// display(3, "a"); // Error: Argument of type 'string' is not assignable to parameter of type 'number'.
Explanation:
The function
display
has two type parameters,T
andU
, with a constraint onU
that it must extend thenumber
type.This ensures that
valTwo
must be a number.The first call
display(3, 2)
is valid, but the second calldisplay(3, "a")
results in a type error as a string is not assignable to a parameter of type number.
Type parameter constraints enhance type safety by enforcing specific conditions on generic types.
Stay tuned for more TypeScript insights and practical tips!
Subscribe to my newsletter
Read articles from Abdul Shaik directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by