DEV Community

Amanpreet Singh
Amanpreet Singh

Posted on • Originally published at blog.amanpreet.dev on

Top 9 Essential Utility Types in TypeScript

Top 9 Essential Utility Types in TypeScript

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"
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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.
Enter fullscreen mode Exit fullscreen mode

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"],
};
Enter fullscreen mode Exit fullscreen mode

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",
};
Enter fullscreen mode Exit fullscreen mode

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
};
Enter fullscreen mode Exit fullscreen mode

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";
Enter fullscreen mode Exit fullscreen mode

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";
Enter fullscreen mode Exit fullscreen mode

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" }>
Enter fullscreen mode Exit fullscreen mode

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)