# Types and Interfaces

## What are Types and Interfaces?

**Types** and **interfaces** both let you describe the shape of an object.

In React, we often use them for declaring **props, state, API responses,** and **config objects**.

```tsx
// Using type
type User = {
  id: string;
  name: string;
  age?: number; // optional
};

// Using interface
interface Product {
  id: number;
  title: string;
}
```

## When to Use What?

### Interface

Use `interface` when you're working with **object-like structures** such as props and API response types.

Interfaces can be extended using⁣ `extends` , making it easy to reuse and compose types in a clean, modular way.

```tsx
interface User {
  id: string;
  name: string;
  age?: number; // Optional
}

// Extend User to include email for registered users
interface RegisteredUser extends User {
  email: string;
  isVerified: boolean;
}

const guestUser: User = {
  id: "guest-01",
  name: "Guest"
};

const registeredUser: RegisteredUser = {
  id: "user-123",
  name: "Alice",
  age: 25,
  email: "alice@example.com",
  isVerified: true
};
```

> 💡 React Tip: Prefer `interface` for component props because they’re extendable.

### Type

Use `type` for **unions, primitives,** or when combining complex types.

#### Union Types

```tsx
type Status = 'loading' | 'success' | 'error'; // union type

const showStatus = (status: Status) : void => {
  if (status === 'loading') {
    console.log('Please wait...');
  }
}

showStatus('loading'); // "Please wait..."
showStatus('success'); // Print nothing
```

#### Discriminated Unions (Tagged Unions)

Useful for modeling variants like UI components and API states.

```tsx
type TextInput = { type: 'text'; placeholder: string };
type CheckboxInput = { type: 'checkbox'; checked: boolean };

// Now the FormInput takes in either TextInput or CheckboxInput
type FormInput = TextInput | CheckboxInput;

const renderInput = (input: FormInput) : JSX.Element => {
  // render the input based on the type accordingly
  if (input.type === 'text') {
    return <input type="text" placeholder={input.placeholder} />;
  }
  return <input type="checkbox" checked={input.checked} />;
}
```

#### Function Types

```tsx
type Callback = (value: string) => void;

const onChange: Callback = (val) => {
  console.log('Changed:', val);
};
```

This is often used in props like `onClick`, `onSubmit`, or custom event handlers in React components.

#### Tuple Types

```tsx
type NameAndAge = [string, number];

const person: NameAndAge = ['Alice', 30];

// Destructuring
const [name, age] = person;
```

Tuples are great because they allow each element in the array to be a known type of value.

#### Mapped Types with type

```tsx
type Keys = 'title' | 'description';
type FieldMap = {
  [K in Keys]: string;
};

// Same as:
// type FieldMap = {
//   title: string;
//   description: string;
// };
```

#### Combining Types with & (Intersection)

```tsx
type WithTimestamp = { createdAt: Date; updatedAt: Date };
type Post = { id: string; content: string };

type PostWithTimeStamp = Post & WithTimestamp;

const post: PostWithTimeStamp = {
  id: 'p1',
  content: 'Hello world!',
  createdAt: new Date(),
  updatedAt: new Date()
};
```
