Extract<Type, Union> Utility Types in TypeScript With Examples
What Is Extract<Type, Union>
The Extract<Type, Union>
utility type in TypeScript is a powerful and
convenient
feature that allows developers to create new types by extracting specific types
from a union type. This utility type can be particularly useful when you want to
narrow down a larger union type to a more specific subset, making it easier to
work with and understand.
Syntax
Here's what the basic syntax looks like:
type NewType = Extract<Type, Union>;
Type
: This is the type you want to extract from the union. It can be a single type or a union type itself. TheType
is compared with each member of theUnion
to determine which types to extract.
Union
: This is the union type from which you want to extract the specific
types.
It consists of two or more types combined with the |
(pipe) symbol.
To demonstrate the syntax, let's consider a simple example:
type Animal = "Dog" | "Cat" | "Fish" | "Bird";
type Pet = Extract<Animal, "Dog" | "Cat">; // Result: "Dog" | "Cat"
In this example, we have an Animal
union type containing four different types
of
animals. Using the Extract
utility type, we can create a new Pet
type
containing
only the animals that match our criteria (in this case, "Dog" and "Cat").
Time To Transition From JavaScript To TypeScript
Level Up Your TypeScript And Object Oriented Programming Skills. The only complete TypeScript course on the marketplace you building TypeScript apps like a PRO.
SEE COURSE DETAILSApplication Example
Let's consider a task management system where users can create and manage
different types of tasks, such as "Meeting", "Deadline", "Reminder", and "
Event". We want to implement a function that filters out only the "Meeting"
and "Deadline" tasks to display on a specific view. Using the
Extract<Type, Union>
utility type, we can achieve this easily and in a
type-safe manner.
First, let's define our union type TaskType
and the Task
interface:
type TaskType = "Meeting" | "Deadline" | "Reminder" | "Event";
interface Task {
id: number;
title: string;
type: TaskType;
date: Date;
}
Now, we'll create a type alias RelevantTaskType
using the Extract
utility
type
to include only "Meeting" and "Deadline" task types:
type RelevantTaskTypes = Extract<TaskType, "Meeting" | "Deadline">;
// Result: "Meeting" | "Deadline"
Next, we implement the function filterRelevantTasks
that takes an array of
tasks
and returns only those with types matching the RelevantTaskTypes
:
function filterRelevantTasks(tasks: Task[]): Task[] {
return tasks.filter(
(task) => task.type === "Meeting" || task.type === "Deadline"
);
}
Finally, let's create an array of tasks and use the filterRelevantTasks
function:
const tasks: Task[] = [
{ id: 1, title: "Team Meeting", type: "Meeting", date: new Date() },
{ id: 2, title: "Project Deadline", type: "Deadline", date: new Date() },
{ id: 3, title: "Doctor's Appointment", type: "Reminder", date: new Date() },
{ id: 4, title: "Conference", type: "Event", date: new Date() },
];
const relevantTasks = filterRelevantTasks(tasks);
console.log(relevantTasks);
The filterRelevantTasks
function will return an array containing only the
"Meeting" and "Deadline" tasks, as specified by the RelevantTaskTypes
type
alias.
Combining Extract
With Other Utility Types
In this example, we will combine the Extract<Type, Union>
utility type with
the
Partial<Type>
utility type in TypeScript. The Partial<Type>
utility type
creates
a new type with all properties of the given Type set as optional. In the
process we are also going to use mapped types as well as Record
type.
Let's assume we have a Person type and a Student type, both having a common property, age. We want to extract the common properties and create a new type with those properties set as optional.
First, define the Person and Student types:
type Person = {
name: string;
age: number;
address: string;
};
type Student = {
age: number;
grade: number;
};
Next, we'll create a union type PersonAndStudent
to combine both types:
type PersonAndStudent = Person | Student;
Now, let's use the Extract<Type, Union>
utility type to get the common
properties, age in this case:
type CommonProperties = {
[K in keyof PersonAndStudent]: (Person[K] extends PersonAndStudent[K]
? K
: never) &
(Student[K] extends PersonAndStudent[K] ? K : never);
}[keyof PersonAndStudent];
The CommonProperties
type will result in the union type "age".
Finally, we'll use the Partial<Type>
utility type to create a new type with
the extracted common property set as optional:
type PartialCommonProperties = Partial<Record<CommonProperties, number>>;
The PartialCommonProperties type will be:
// {
// age?: number;
// }
Conclusion
By comparing the given Type
with each member of the Union
, the Extract
utility
type forms a new union type containing only the matching types. This versatile
feature can be applied in various scenarios, such as filtering out certain types
or refining function argument types, contributing to a more robust and type-safe
codebase.
Furthermore, the Extract<Type, Union>
utility type can be combined with other
utility types, such as Partial<Type>
, to create even more tailored and powerful
types.
What Can You Do Next 🙏😊
If you liked the article, consider subscribing to Cloudaffle, my YouTube Channel, where I keep posting in-depth tutorials and all edutainment stuff for software developers.