ts-utility-type

Utility Type

In TypeScript, there is a type called Utility Types that helps us modify existing types without changing them

Partial<Type>

It's the opposite of Required<Type>. It makes all properties of the given type Optional

interface Person {
  name: string;
  age: number;
  adress?: string;
}

const person1: Person = {
  name: "John",
  age: 30,
};

type PartialPerson = Partial<Person>;

const person2: PartialPerson = {
  name: "John",
};

This code example demonstrates the use of the Partial utility type in TypeScript.

  • First, a Person interface is defined. This interface includes name and age properties as required, and the address property as optional.
  • The person1 object is created in accordance with the Person interface. The name and age properties are provided, while the optional address property is omitted.
  • Then, using Partial<Person>, a PartialPerson type is created. The Partial utility makes all properties in the Person interface optional.
  • Finally, the person2 object is created of type PartialPerson. This object only contains the name property, because thanks to Partial, all properties have become optional.

Thus, thanks to the Partial utility type, we can create an object by selecting the properties we want without having to include all the properties of the original Person interface.

Required<Type>

Makes all properties of the type given as a parameter (Type) required.

interface Person {
  name: string;
  age: number;
  adress?: string;
}

const person1: Person = {
  name: "John",
  age: 30,
};


type RequiredPerson = Required<Person>;

const person3: RequiredPerson = {
  name: "John",
  age: 30,
  adress: "New York",
  // email: "john@example" // die Email Eigenschaft sollte unbedingt verwendet werden
};

This code example demonstrates the use of the Required utility type in TypeScript.

  • First, a Person interface is defined. In this interface, the name and age properties are required, while the address property is optional (indicated by a question mark).
  • The person1 object is created in accordance with the original Person interface. It only contains the required name and age properties.
  • Then, using Required<Person>, a RequiredPerson type is created. The Required utility makes all properties in the Person interface required.
  • Finally, the person3 object is created of type RequiredPerson. This object must now contain all properties (name, age, and address) because Required has made all properties mandatory.

Thus, thanks to the Required utility type, we make all properties of the original Person interface mandatory. This is useful in situations where we want an object to strictly adhere to a specific structure.

Note: There is a comment line in the code example indicating that the email property should also be used, but this property is not defined in the original Person interface. This is likely an error or missing definition.

Pick<Type, Keys>

Allows us to take some properties from a given type and create a new type.

// ! Pick allows you to extract only certain properties of a type
interface Product {
    id: number;
    name: string;
    price: number;
    description: string;
    price: number;
    category: string;
}

const product_eins: Product = {
    id: 1,
    name: "Product 1",
    price: 100,
    description: "Description",
    category: "Category"
}

console.log(product_eins)

type PickProduct = Pick<Product, "id" | "name" | "price">;

const product_zwei: PickProduct = {
    id: 2,
    name: "Product 2",
    price: 200
}

console.log(product_zwei)

This code example demonstrates the usage of the Pick utility type in TypeScript.

First, a Product interface is defined. This interface contains the following properties:

  • id: number
  • name: string
  • price: number
  • description: string
  • category: string

Then, a PickProduct type is created using Pick<Product, "id" | "name" | "price">:

type PickProduct = Pick<Product, "id" | "name" | "price">;

This new PickProduct type contains only the "id", "name", and "price" properties from the original Product interface. The Pick utility allows you to create a new type by selecting specific properties from an existing type.

Finally, an object named product_zwei is created of the PickProduct type:

const product_zwei: PickProduct = {
    id: 2,
    name: "Product 2",
    price: 200
}

This object must only contain the properties specified in the PickProduct type ("id", "name", and "price").

The Pick utility is useful when you want to create a new type that contains only specific properties from an existing type.

Omit<Type, Keys>

We can think of this as the opposite of Pick<Type,Keys>. Instead of taking some properties from a type to create a new type, it allows us to create a new type by removing some properties.

// ! Omit removes certain properties


type ProductWithOutDesc = Omit<Product, "desc">

const product_drei: ProductWithOutDesc = {
    id: 3,
    name: "Laptop",
    price: 1200,
    category: "Electronics"
}

console.log(product_drei);

This code example demonstrates the usage of the Omit utility type in TypeScript.

  • First, a new type is created using the Omit utility type:

This creates a new type by removing the "desc" property from the Product type.

type ProductWithOutDesc = Omit<Product, "desc">

Then, an object is created using this new type:

const product_drei: ProductWithOutDesc = {
    id: 3,
    name: "Laptop",
    price: 1200,
    category: "Electronics"
}
  • This object contains all the properties of the Product type except for the "desc" property, in accordance with the ProductWithOutDesc type.
  • Finally, the created object is printed using console.log:

The Omit utility type is useful when you want to create a new type by removing specific properties from an existing type. In this example, a new type has been created by removing the "desc" property from the Product type.

Record<Keys, Type>

It allows us to create a new type by combining two given types as key and value. The combination is done with the first parameter as the key and the second parameter as the value.

type PermissionLevel = "ADMIN" | "USER" | "GUEST";

type Permission = Record<PermissionLevel, string[]>;

const userPermission: Permission = {
  ADMIN: ["READ", "WRITE", "DELETE"],
  USER: ["READ", "UPDATE"],
  GUEST: ["READ"],
};

if (userPermission.ADMIN.includes("WRITE")) {
  console.log("Yuu are admin");
  
} else if (userPermission.USER.includes("UPDATE")) {
  console.log("You are user");
}else if (userPermission.GUEST.includes("READ")) {
  console.log("You are guest");
}

This code example demonstrates the use of the Record utility type in TypeScript.

  • First, a PermissionLevel type is defined:
type PermissionLevel = "ADMIN" | "USER" | "GUEST";

This is a union type with three possible values.

  • Then, a Permission type is created using the Record utility type:
type Permission = Record<PermissionLevel, string[]>;

This creates an object type containing a string array for each PermissionLevel.

  • A userPermission object is created:
const userPermission: Permission = {
  ADMIN: ["READ", "WRITE", "DELETE"],
  USER: ["READ", "UPDATE"],
  GUEST: ["READ"],
};

This object contains the allowed actions for each permission level.

  • Finally, an if-else block is used to check the user's permission:
if (userPermission.ADMIN.includes("WRITE")) {
  console.log("Yuu are admin");
} else if (userPermission.USER.includes("UPDATE")) {
  console.log("You are user");
} else if (userPermission.GUEST.includes("READ")) {
  console.log("You are guest");
}

This block prints the appropriate message to the console based on the user's permission level.

The Record utility type is useful for defining key-value pairs of an object. In this example, it was used to define different permission levels and their corresponding permissions.

Readonly<Type>

You can create a new type by making all properties of the given type readonly.

type ReadOnlyProduct = Readonly<Product>;
const product_four: Product = {
  id: 1,
  name: "Product 4",
  price: 100,
  description: "Description",
  category: "Category",
};

product_four.price = 200; // erlaubt, weil die Eigenschaft nicht readonly ist

const product_five: ReadOnlyProduct = {
  id: 1,
  name: "Product 5",
  price: 100,
  description: "Description",
  category: "Category",
};

// product_five.price = 200; // Error, weil die Eigenschaft readonly ist

This example demonstrates the use of the Readonly utility type in TypeScript:

  • First, a new type called ReadOnlyProduct is created:
type ReadOnlyProduct = Readonly<Product>;

This creates a new type by making all properties of the Product type readonly.

  • Then, a normal Product object is created:
const product_four: Product = {
  id: 1,
  name: "Product 4",
  price: 100,
  description: "Description",
  category: "Category",
};

The properties of this object can be modified.

  • For example, it is possible to change the price:
product_four.price = 200; // izin verilir, çünkü özellik readonly değil
  • Then, an object of type ReadOnlyProduct is created:
const product_five: ReadOnlyProduct = {
  id: 1,
  name: "Product 5",
  price: 100,
  description: "Description",
  category: "Category",
};

All properties of this object are readonly.

  • Finally, as shown in the comment, attempting to modify the properties of this readonly object will result in an error:
// product_five.price = 200; // Hata, çünkü özellik readonly

The Readonly utility type is useful when you want to prevent the properties of an object from being modified. This is particularly helpful when creating immutable data structures.

Exclude<Type>

type BasicColors = "RED" | "BLUE" | "GREEN" | "YELLOW" | "BLACK" | "WHITE";

type RealColors = Exclude<BasicColors, "BLACK" | "WHITE">;

function showColors(color: RealColors) {
  console.log(color);
}

// showColors("BLACK"); // Error

showColors("RED");

This code example demonstrates the use of the Exclude utility type in TypeScript. Here's the explanation:

  • First, a union type named BasicColors is defined:
type BasicColors = "RED" | "BLUE" | "GREEN" | "YELLOW" | "BLACK" | "WHITE";

This is a type containing six basic colors.

  • Next, a new type called RealColors is created using the Exclude utility type:
type RealColors = Exclude<BasicColors, "BLACK" | "WHITE">;

This creates a new type by excluding "BLACK" and "WHITE" colors from BasicColors.

  • A function named showColors is defined:
function showColors(color: RealColors) {
  console.log(color);
}

This function accepts only a parameter of type RealColors.

  • As shown in the comment line, passing the color "BLACK" as a parameter to this function will result in an error:
// showColors("BLACK"); // Error

Because "BLACK" is not in the RealColors type.

  • Finally, the function is called with the color "RED":
showColors("RED");

This is a valid call because "RED" is of type RealColors.

The Exclude utility type is useful when you want to create a new type by removing certain values from an existing type. In this example, a new color type has been created by excluding black and white from the basic colors.

Popular Tag
Share:

Leave a reply