# TypeScript `Partial`, `Required`, and `Readonly`

TypeScript provides built-in utility types to transform the properties of an interface or type alias. Three of the most fundamental utilities deal with property modifiers: optionality (`?`) and immutability (`readonly`).

## 1. `Partial<Type>`

`Partial<Type>` constructs a type with all properties of `Type` set to optional. This is useful when you need to update an object but might only have a subset of the fields.

### Example

```typescript
interface User {
  id: number;
  name: string;
  email: string;
}

// All fields become optional: { id?: number; name?: string; email?: string; }
type PartialUser = Partial<User>;

function updateUser(user: User, fieldsToUpdate: Partial<User>) {
  return { ...user, ...fieldsToUpdate };
}

const user = { id: 1, name: "Alice", email: "alice@example.com" };
updateUser(user, { name: "Bob" }); // OK: We didn't provide 'email' or 'id'
```

## 2. `Required<Type>`

`Required<Type>` is the opposite of `Partial`. It constructs a type consisting of all properties of `Type` set to required. It removes the `?` modifier from all properties.

### Example

```typescript
interface Config {
  host?: string;
  port?: number;
  timeout?: number;
}

// All fields become required: { host: string; port: number; timeout: number; }
type CompleteConfig = Required<Config>;

const defaultConfig: CompleteConfig = {
  host: "localhost",
  port: 8080,
  timeout: 5000
};

// Error: Property 'timeout' is missing in type...
// const badConfig: CompleteConfig = {
//   host: "localhost",
//   port: 3000
// };
```

## 3. `Readonly<Type>`

`Readonly<Type>` constructs a type with all properties of `Type` set to `readonly`. This means the properties of the constructed type cannot be reassigned.

### Example

```typescript
interface Todo {
  title: string;
}

const todo: Readonly<Todo> = {
  title: "Delete inactive users"
};

// todo.title = "Hello"; // Error: Cannot assign to 'title' because it is a read-only property.
```

**Note:** This is shallow immutability. If a property is an object, the properties of that nested object are still mutable unless recursively frozen.

## 4. How they work (Under the hood)

These types are implemented using **Mapped Types**.

```typescript
// Partial
type Partial<T> = {
    [P in keyof T]?: T[P];
};

// Required
type Required<T> = {
    [P in keyof T]-?: T[P]; // The -? removes the optional modifier
};

// Readonly
type Readonly<T> = {
    readonly [P in keyof T]: T[P];
};
```

[[programming/javascript/typescript/typescript]]
[[programming/javascript/typescript/utility-types]]