Why use TypeScript?
Typescript is a strongly typed superset of Javascript that gives you better tooling at any scale, enabling developers to catch errors at compile time rather than runtime.
TypeScript brings
Type Safety
Scalability
Enhanced IDE support
What are Utility Types?
Utility types are predefined types that help manipulate and transform other types. They help in simplifying complex type definitions.
By understanding and effectively using these utility types, you can write more concise, readable, and maintainable code, making your development process smoother and more efficient. These utilities are available globally.
Let's explore the top 9 utility types in TypeScript, with examples and explanations of how they can streamline your code.
Partial<Type>
Constructs a type with all properties of Type
set to optional.
interface User {
name: string;
age: number;
}
const updatedUser: Partial<User> = {
name: "Aman"
}
In the above code, the interface User
has two required properties. However, by using the Partial<User>
type, we can make these properties optional.
This can be useful in update operations where all the fields are not provided.
Required<Type>
Constructs a type containing all properties of Type
set to required. You can consider this the opposite of Partial<Type>
interface User {
name?: string;
age?: number;
}
const newuser: Required<User> = {
name: "Aman"
}
// error as `age` is missing in the newuser
The above code will give you the following error -
Property 'age' is missing in type '{ name: string; }' but required in type 'Required<User>'.
This utility is beneficial where all the properties are required.
Readonly<Type>
This utility constructs a type with all the properties of the Type
sets to readonly
, meaning the properties of the newly constructed type cannot be reassigned.
In other words, all the properties of a type Type
are immutable.
interface User {
name: string;
age: number;
}
const user: Readonly<User> = {
name: "Aman",
age: 30,
};
user.name = 'Naman';
// Error: Cannot assign to 'name' because it is a read-only property.
This utility type can be used to avoid and protect objects from accidental mutations.
Record<Keys, Type>
Constructs an object type whose property keys are Keys
and whose property values are Type
. This utility helps map the properties of a type to another type.
type Role = "admin" | "user" | "moderator";
type Permission = "read" | "write" | "delete";
const roles: Record<Role, Permission[]> = {
admin: ["read", "write", "delete"],
user: ["read"],
moderator: ["read","write"],
};
This utility helps map the properties of a type to another type.
Pick<Type, Keys>
Constructs a type by picking the set of properties Keys
from Type
interface User {
name: string;
age: number;
email: string;
}
type UserContactInfo = Pick<User, "name" | "email">;
const contact: UserContactInfo = {
name: "Aman",
email: "aman@example.com",
};
The utility type Pick<T, K>
is very useful when you only need a subset of properties from a larger type.
Omit<Type, Keys>
Constructs a type by picking all the properties of Type
and then removing Keys
. This type is an opposite version of Pick<T, K>
.
interface User {
name: string;
age: number;
email: string;
password: string;
}
type PublicUser = Omit<User, "password">;
const publicUser: PublicUser = {
name: "Aman",
email: "aman@example.com",
age: 38
};
The utility type Omit<T, K>
is useful when you need to exclude sensitive or unnecessary properties.
NonNullable<Type>
Constructs a type by excluding null
and undefined
from the defined Type
.
type Name = string | null | undefined;
const username: NonNullable<Name> = "Aman";
The NonNullable<T>
type is useful for making sure a value is always present, which helps avoid potential runtime errors.
Exclude<Type, Union>
Constructs a type by excluding from Type
those types that are assignable to Union
.
type Status = "success" | "error" | "pending";
type ErrorStatus = Exclude<Status, "success" | "pending">;
const error: ErrorStatus = "error";
The constant error
will have excluded value from the type ErrorStatus
. This type is useful for refining types by excluding or removing specific values.
Extract<Type, Union>
Constructs a type by extracting from Type
those types that are assignable to Union
.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; x: number }
| { kind: "triangle"; x: number; y: number };
type Design = Extract<Shape, { kind: "circle" }>
In the above code, the type Design
will be the type { kind: "circle"; radius: number; }
. The Extract<T, U>
utility type can be used to isolate specific types or values from a union.
Final Thoughts
These utility types are powerful tools in TypeScript. They let you manipulate and transform types in a way that is both clear and concise.
The utility types are not limited to those mentioned above; there are a few more utility types you can use in your projects such as
ReturnType<Type>
Parameters<Type>
ConstructorParameters<Type>
and a few more
Conclusion
That's it for today, and congratulations to everyone who has followed this article! You've successfully learned about the top 9 utility types in Typescript. Go and implement them in your projects! π
I hope you have learned something new, just as I did. If you enjoyed this article, please like and share it. Also, follow me to read more exciting articles. You can check out my social links here.
Top comments (0)