Variadic Tuple Types in TypeScript

Just a guy who loves to write code and watch anime.
Arrays in TypeScript
We want to store information about a user's profile settings:
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 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:
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:
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:
// 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:
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.






