# Variadic Tuple Types in TypeScript

# Arrays in TypeScript

We want to store information about a user's profile settings:

```typescript
type ProfileSettings = string[];

const settings: ProfileSettings = [
  "darkMode", // theme
  "compact", // layout
  "12", // fontSize
  "true", // notifications
];
```

The problem?

This array type is too flexible. Any string can be placed anywhere. We might accidentally switch positions or add wrong values.

```typescript
// TypeScript is perfectly happy with this
const brokenSettings: ProfileSettings = [
  "12", // fontSize in wrong position
  "darkMode", // theme in wrong position
  "invalid", // random value
  "compact", // layout in wrong position
  "extra", // unexpected extra value
];
```

We need more precision.

# Tuple Types

Enter tuple types:

```typescript
type ProfileSettings = [
  theme: string,
  layout: string,
  fontSize: string,
  notifications: string
];
```

Better. Now we have fixed positions. But we're still using strings for everything. We can make it even more precise:

```typescript
type Theme = "darkMode" | "lightMode";
type Layout = "compact" | "comfortable";
type ProfileSettings = [
  theme: Theme,
  layout: Layout,
  fontSize: number,
  notifications: boolean
];

// Now TypeScript catches our mistakes
const settings: ProfileSettings = ["darkMode", "compact", 16, true];
```

This works great for fixed structures. But what if we need flexibility?

# Variadic Tuple Types

Imagine we want to create a function that adds a timestamp to any settings tuple:

```typescript
// We want this to work for ANY tuple
function addTimestamp<T extends unknown[]>(settings: T): [...T, number] {
  return [...settings, Date.now()];
}
```

This is where variadic tuple types come in. They let us work with tuples of any length while preserving their structure:

```typescript
type WithTimestamp<T extends unknown[]> = [...T, number];

// Works with any tuple while maintaining type safety
type UserSettings = [string, boolean];
type TimestampedSettings = WithTimestamp<UserSettings>; // [string, boolean, number]

type FullSettings = [string, boolean, number, string];
type TimestampedFull = WithTimestamp<FullSettings>; // [string, boolean, number, string, number]
```

We've gone from using loose array types to precise tuples, and now to flexible, type-safe variadic tuples. Each step makes our code safer while keeping the flexibility we need.

This approach is really useful when creating type-safe tools that need to handle tuples of various lengths and types.
