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!