paint-brush
Utility types in Typescript - Part 1: Partial, Required, Readonlyby@andemosa
5,363 reads
5,363 reads

Utility types in Typescript - Part 1: Partial, Required, Readonly

by Anderson OsayerieMay 22nd, 2022
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

Typescript allows developers to create new custom types as necessary during development. Typesript provides some globally available utility types. These utility types allows the developer to carry out type transformations. The utility type Partial creates a new type where all the properties of the input type T are set to optional. The utility type Required creates a new type where all the properties of the input type `T` are set to required. It is the opposite of Partial. The utility type Readonly creates a new type where all the properties of the input type T are set to readonly.

Company Mentioned

Mention Thumbnail
featured image - Utility types in Typescript - Part 1: Partial, Required, Readonly
Anderson Osayerie HackerNoon profile picture


Typescript allows developers to use static type-checking in JavaScript. It also adds the ability to create new custom types as necessary during development. Asides from allowing the creation of new types, Typescript also allows for the transformation of existing types.


Typescript provides some globally available utility types. These utility types allows the developer to carry out these common type transformations.


In this article we look at some commonly used Utility types and when we can use them in our code.


Partial<T>

The utility type Partial creates a new type where all the properties of the input type T are set to optional.


interface Point {
  x: number;
  y: number;
  z?: number;
}

type PointPartial = Partial<Point>
// {
//     x?: number;
//     y?: number;
//     z?: number;
// }


It can be used to type the parameter of a function that is used to update the properties of an object as can be seen in the example below.


interface User {
  firstName: string;
  lastName: string;
  age: number;
}

const updateUser = (user: User, updatedFields: Partial<User>) => ({
  ...user,
  ...updatedFields,
});

const user1: User = {
  firstName: "Anderson",
  lastName: "Osayerie",
  age: 27,
};

const user2 = updateUser(user1, { age: 28 });

console.log(user2); // { name: "Anderson", surname: "Osayerie", age: 28 }



Required<T>

The utility type Required creates a new type where all the properties of the input type T are set to required. It is the opposite of Partial.


interface Point {
  x: number;
  y: number;
  z?: number;
}

type PointRequired = Required<Point>;
// {
//     x: number;
//     y: number;
//     z: number;
// }


Below is an example of where we can use the Required type. The Todo interface with the ID property being optional can be used when creating the todo because we do not know the ID at that point. But when we want to update the todo, we have to make sure the ID is set.


interface Todo {
  id?: number;
  title: string;
  description: string;
}

const createTodo = (todo: Todo) => {
  const newTodo = db.create(todo);
  return newTodo;
};

const updateTodo = (todo: Required<Todo>) => {
  const updatedTodo = db.update(todo);
  return updatedTodo;
};

createTodo({
  title: "Write article",
  description: "Choose topic",
});

updateTodo({
  id: 3,
  title: "Write article",
  description: "Topic choosen",
});



Readonly<T>

The utility type Readonly creates a new type where all the properties of the input type T are set to readonly. The properties of the new type cannot be reassigned.


interface Point {
  x: number;
  y: number;
  z?: number;
}

type PointReadonly = Readonly<Point>;
// {
//     readonly x: number;
//     readonly y: number;
//     readonly z?: number;
// }


The Readonly utility is useful for showing assignment expressions that would fail at runtime. This occurs when trying to reassign the properties of a frozen object.


interface User {
  firstName: string;
  lastName: string;
  age: number;
}

const freeze = <T>(obj: T): Readonly<T> => Object.freeze(obj);

const user: User = {
  firstName: "Anderson",
  lastName: "Osayerie",
  age: 27,
};

const readonlyUser = freeze(user);

// Cannot assign to 'age' because it is a read-only property
readonlyUser.age = 28;


Conclusion

In this article we have considered three built-in utility types provided by Typescript and how we can use them in our code.

  • Partial that creates a new type where all the properties are set to optional.
  • Required that creates a new type where all the properties are set to required.
  • Readonly that creates a new type where all the properties are set to readonly.