# TypeScript Utility Types: Making Your Code More Efficient

## Introduction

TypeScript is a powerful tool for writing scalable and maintainable JavaScript applications. One of its best features is **Utility Types**, which help developers **modify, filter, or transform types** without rewriting them from scratch. These built-in types make code **more reusable, readable, and error-proof**.

If you’ve ever found yourself manually tweaking a type definition, TypeScript Utility Types can save you a lot of time! In this article, we’ll explore the most useful utility types and how they make coding in TypeScript easier and more efficient.

## What Are TypeScript Utility Types?

Utility Types in TypeScript are **predefined generic types** that let you **modify existing types**. Instead of manually creating a new type, you can use these utilities to quickly create a variation of an existing type.

Think of them like **shortcuts** that help you avoid unnecessary duplication and make your code more flexible.

## Essential TypeScript Utility Types

Here are some of the most commonly used Utility Types with examples:

### **1\.** `Partial<T>` - Makes All Properties Optional

This utility makes all properties of an object **optional**, allowing you to define only some values while keeping the original structure.

```ts
type User = {
  name: string;
  age: number;
};

const user: Partial<User> = { name: "John" }; // ✅ No error, 'age' is optional
```

### **2\.** `Required<T>` - Makes All Properties Required

Opposite to `Partial`, this utility makes all properties **mandatory**, even if they were originally optional.

```ts
type User = {
  name?: string;
  age?: number;
};

const user: Required<User> = { name: "John" }; // ❌ Error if 'age' is missing
```

### **3\.** `Readonly<T>` - Prevents Modifications

This utility ensures that once an object is created, its properties **cannot be changed**.

```ts
type User = {
  name: string;
  age: number;
};

const user: Readonly<User> = { name: "John", age: 25 };
user.name = "Doe"; // ❌ Error: Cannot modify readonly property
```

### **4\.** `Pick<T, K>` - Selects Specific Properties

This utility allows you to create a new type by selecting only **certain properties** from an existing type.

```ts
type User = {
  name: string;
  age: number;
  email: string;
};

type NameOnly = Pick<User, "name">; // { name: string }
```

### **5\.** `Omit<T, K>` - Removes Specific Properties

Similar to `Pick`, but instead of selecting, it **removes** specific properties from a type.

```ts
type User = {
  name: string;
  age: number;
  email: string;
};

type NoEmail = Omit<User, "email">; // { name: string; age: number }
```

## Advanced TypeScript Utility Types

### **6\.** `Record<K, T>` - Creates an Object Type with Fixed Keys

This utility helps define an object **with specific keys and a common value type**.

```ts
type Roles = Record<"admin" | "user" | "guest", string>;

const roleNames: Roles = {
  admin: "Administrator",
  user: "Registered User",
  guest: "Visitor",
};
```

### **7\.** `Exclude<T, U>` - Removes Specific Types from a Union

Used to remove one or more types from a **union type**.

```ts
type Status = "success" | "error" | "pending";
type ActiveStatus = Exclude<Status, "pending">; // "success" | "error"
```

### **8\.** `Extract<T, U>` - Keeps Only Specific Types from a Union

The opposite of `Exclude`, it picks only the matching types.

```ts
type Status = "success" | "error" | "pending";
type ErrorStatus = Extract<Status, "error">; // "error"
```

### **9\.** `NonNullable<T>` - Removes `null` and `undefined`

Ensures a type **does not include** `null` or `undefined`.

```ts
type Data = string | null | undefined;
type CleanData = NonNullable<Data>; // string
```

### **10\.** `ReturnType<T>` - Gets the Return Type of a Function

Extracts the return type from a function.

```ts
function getAge(): number { return 25; }
type Age = ReturnType<typeof getAge>; // number
```

### **11\.** `Parameters<T>` - Gets Function Parameter Types

Extracts the parameters of a function as a tuple.

```ts
function greet(name: string, age: number) {}
type GreetParams = Parameters<typeof greet>; // [string, number]
```

### **12\.** `ConstructorParameters<T>` - Gets Constructor Parameters

Extracts parameters from a class constructor.

```ts
class Person {
  constructor(public name: string, public age: number) {}
}
type PersonParams = ConstructorParameters<typeof Person>; // [string, number]
```

### **13\.** `InstanceType<T>` - Gets the Instance Type of a Class

Extracts the type of an instance of a class.

```ts
class Car { name: string = "Tesla"; }
type CarInstance = InstanceType<typeof Car>; // Car
```

## Conclusion

TypeScript **Utility Types** are incredibly useful for improving **code reusability, reducing redundancy, and making type definitions more flexible**. Whether you're simplifying object structures, extracting properties, or enforcing immutability, these utilities help you write **better, safer, and more maintainable** TypeScript code.

By mastering these utility types, you'll be able to write cleaner, more efficient code while minimizing errors. Next time you find yourself modifying types manually, check if there's a utility type that can **do the work for you**!
