👉 A tuple is a fixed-length array where each element has a specific type and position.
Unlike regular arrays (where all elements are of the same type), tuples let you define different types at different positions.
⚡ Syntax
let tupleName: [Type1, Type2, ..., TypeN] = [value1, value2, ..., valueN];✍ Example
let user: [string, number] = ["Alice", 30];✅ This tuple:
The first element is a
stringThe second element is a
number
console.log(user[0]); // "Alice"
console.log(user[1]); // 30❌ If you try:
user = [30, "Alice"]; // Error: types are in the wrong order🚀 Common use cases
Represent a pair of values (e.g. coordinates, key-value pairs)
Return multiple values from a function
Represent structured data without creating a full interface
⚙ Tuples with optional elements
let point: [number, number, number?] = [10, 20];✅ The third value is optional.
⚡ Readonly tuples
const pair: readonly [string, number] = ["id", 101];
// pair[0] = "newId"; ❌ Error: Cannot assign to readonly element⚡ Tuple with rest elements
let rgb: [number, number, number, ...string[]] = [255, 0, 0, "red", "bright"];✅ First 3 are numbers, then any number of strings.
💡 Accessing elements
Elements have their specific types:
let data: [string, boolean] = ["loaded", true];
let status: string = data[0];
let flag: boolean = data[1];Trying to access beyond the defined length:
console.log(data[2]); // TS error or `undefined` at runtime<div class="infographic-ts" id="infographic-ts">
<style>
.infographic-ts {
--body-font: system-ui, -apple-system, sans-serif;
--mono-font: ui-monospace, SFMono-Regular, Consolas, "Courier New", monospace;
--ed-bg: #1e1e1e;
--ed-bar: #2a2a2a;
--ed-out: #d4d4d4;
--ed-muted: #8a8a8a;
--ed-ok: #4ec9b0;
--ed-err: #f14c4c;
--run-bg: #2e7d46;
--run-bg-hover: #35924f;
--tok-kw: #c586c0;
--tok-type: #4ec9b0;
--tok-str: #ce9178;
--tok-num: #b5cea8;
--tok-punc: #d4d4d4;
--tok-cmt: #808080;
--tok-var: #ffffff;
max-width: 680px;
margin: 0 auto;
box-sizing: border-box;
background: transparent;
font-family: var(--body-font);
}
.infographic-ts * { box-sizing: border-box; }
.ts-header { font-family: 'Georgia', 'Fraunces', serif; font-weight: 700;
font-size: 1.9rem; letter-spacing: 0.01em; color: inherit; text-align: center;
margin: 0 0 1.4rem; }
.tabs { display: flex; justify-content: center; gap: 4px; margin-bottom: 1.1rem; }
.tab-btn { font-family: var(--body-font); font-size: 0.82rem; font-weight: 500;
background: #ffffff; color: #2563eb; border: 1px solid #2563eb; padding: 0.65rem 1rem;
cursor: pointer; border-radius: 8px; }
.tab-btn.active { background: #2563eb; color: #ffffff; }
.tab-btn:hover:not(.active) { background: #eef3ff; }
.tab-panel { display: none; background: var(--ed-bg); border-radius: 8px;
padding: 1.1rem; }
.tab-panel.active { display: block; }
.code-window { background: var(--ed-bg); border: 1px solid #2f2f2f; border-radius: 8px;
overflow: hidden; margin-bottom: 1rem; }
.code-window:last-child { margin-bottom: 0; }
.code-topbar { display: flex; align-items: center; justify-content: space-between;
padding: 0.5rem 0.75rem; background: var(--ed-bar); }
.code-dots { display: flex; gap: 6px; }
.code-dot { width: 9px; height: 9px; border-radius: 50%; }
.code-dot.r { background: #ff5f57; }
.code-dot.y { background: #febc2e; }
.code-dot.g { background: #28c840; }
.code-filename { font-family: var(--mono-font); font-size: 0.74rem; color: var(--ed-muted); }
.run-btn { display: inline-flex; align-items: center; gap: 0.35rem; background: var(--run-bg);
color: #fff; border: none; border-radius: 4px; padding: 0.32rem 0.7rem; font-size: 0.74rem;
font-family: var(--body-font); font-weight: 500; cursor: pointer; }
.run-btn:hover { background: var(--run-bg-hover); }
.run-btn svg { width: 10px; height: 10px; }
.code-body { padding: 0.85rem 1.1rem; font-family: var(--mono-font); font-size: 0.8rem;
line-height: 1.65; color: var(--ed-out); white-space: pre; overflow-x: auto; }
.tok-kw { color: var(--tok-kw); }
.tok-type { color: var(--tok-type); }
.tok-str { color: var(--tok-str); }
.tok-num { color: var(--tok-num); }
.tok-punc { color: var(--tok-var); }
.tok-cmt { color: var(--tok-cmt); }
.tok-var { color: var(--tok-var); }
.tok-err { color: var(--ed-err); }
.console { padding: 0 1.1rem; max-height: 0; overflow: hidden; font-family: var(--mono-font);
font-size: 0.78rem; line-height: 1.65; transition: max-height 0.35s ease, padding 0.35s ease; }
.console.show { max-height: 260px; padding: 0 1.1rem 0.85rem; }
.console-line { color: var(--ed-out); }
.console-line.ok { color: var(--ed-ok); }
.console-line.err { color: var(--ed-err); }
</style>
<div class="tabs">
<button class="tab-btn active" data-tab="t1" type="button">Ways to declare tuples</button>
<button class="tab-btn" data-tab="t2" type="button">Types of tuples</button>
<button class="tab-btn" data-tab="t3" type="button">Common tuple operations</button>
</div>
<div class="tab-panel active" id="t1">
<div class="code-window">
<div class="code-topbar">
<div class="code-dots"><span class="code-dot r"></span><span class="code-dot y"></span><span class="code-dot g"></span></div>
<span class="code-filename">basic.ts</span>
</div>
<div class="code-body"><span class="tok-cmt">// fixed length, fixed order, each slot has its own type</span>
<span class="tok-kw">let</span> <span class="tok-var">point</span><span class="tok-punc">:</span> <span class="tok-punc">[</span><span class="tok-type">number</span><span class="tok-punc">,</span> <span class="tok-type">number</span><span class="tok-punc">]</span> <span class="tok-punc">=</span> <span class="tok-punc">[</span><span class="tok-num">10</span><span class="tok-punc">,</span> <span class="tok-num">20</span><span class="tok-punc">];</span>
<span class="tok-kw">let</span> <span class="tok-var">user</span><span class="tok-punc">:</span> <span class="tok-punc">[</span><span class="tok-type">string</span><span class="tok-punc">,</span> <span class="tok-type">number</span><span class="tok-punc">]</span> <span class="tok-punc">=</span> <span class="tok-punc">[</span><span class="tok-str">"Alice"</span><span class="tok-punc">,</span> <span class="tok-num">30</span><span class="tok-punc">];</span></div>
</div>
<div class="code-window">
<div class="code-topbar">
<div class="code-dots"><span class="code-dot r"></span><span class="code-dot y"></span><span class="code-dot g"></span></div>
<span class="code-filename">array-vs-tuple.ts</span>
</div>
<div class="code-body"><span class="tok-cmt">// an array of the same length looks similar, but order and length aren't enforced</span>
<span class="tok-kw">let</span> <span class="tok-var">arr</span><span class="tok-punc">:</span> <span class="tok-punc">(</span><span class="tok-type">string</span> <span class="tok-punc">|</span> <span class="tok-type">number</span><span class="tok-punc">)[]</span> <span class="tok-punc">=</span> <span class="tok-punc">[</span><span class="tok-str">"Alice"</span><span class="tok-punc">,</span> <span class="tok-num">30</span><span class="tok-punc">];</span>
<span class="tok-var">arr</span><span class="tok-punc">.</span><span class="tok-var">push</span><span class="tok-punc">(</span><span class="tok-str">"extra"</span><span class="tok-punc">);</span> <span class="tok-cmt">// fine for an array, not for a tuple</span></div>
</div>
</div>
<div class="tab-panel" id="t2">
<div class="code-window">
<div class="code-topbar">
<div class="code-dots"><span class="code-dot r"></span><span class="code-dot y"></span><span class="code-dot g"></span></div>
<span class="code-filename">optional.ts</span>
</div>
<div class="code-body"><span class="tok-cmt">// optional element with ?</span>
<span class="tok-kw">let</span> <span class="tok-var">entry</span><span class="tok-punc">:</span> <span class="tok-punc">[</span><span class="tok-type">string</span><span class="tok-punc">,</span> <span class="tok-type">number</span><span class="tok-punc">?]</span> <span class="tok-punc">=</span> <span class="tok-punc">[</span><span class="tok-str">"Alice"</span><span class="tok-punc">];</span>
<span class="tok-kw">let</span> <span class="tok-var">entry2</span><span class="tok-punc">:</span> <span class="tok-punc">[</span><span class="tok-type">string</span><span class="tok-punc">,</span> <span class="tok-type">number</span><span class="tok-punc">?]</span> <span class="tok-punc">=</span> <span class="tok-punc">[</span><span class="tok-str">"Bob"</span><span class="tok-punc">,</span> <span class="tok-num">30</span><span class="tok-punc">];</span></div>
</div>
<div class="code-window">
<div class="code-topbar">
<div class="code-dots"><span class="code-dot r"></span><span class="code-dot y"></span><span class="code-dot g"></span></div>
<span class="code-filename">readonly.ts</span>
<button class="run-btn" id="roBtn" type="button">
<svg viewBox="0 0 24 24" fill="currentColor"><polygon points="6 3 20 12 6 21 6 3"/></svg>
run
</button>
</div>
<div class="code-body"><span class="tok-cmt">// readonly tuple — elements can't be reassigned</span>
<span class="tok-kw">let</span> <span class="tok-var">coords</span><span class="tok-punc">:</span> <span class="tok-kw">readonly</span> <span class="tok-punc">[</span><span class="tok-type">number</span><span class="tok-punc">,</span> <span class="tok-type">number</span><span class="tok-punc">]</span> <span class="tok-punc">=</span> <span class="tok-punc">[</span><span class="tok-num">10</span><span class="tok-punc">,</span> <span class="tok-num">20</span><span class="tok-punc">];</span>
<span class="tok-var">coords</span><span class="tok-punc">[</span><span class="tok-num">0</span><span class="tok-punc">]</span> <span class="tok-punc">=</span> <span class="tok-num">15</span><span class="tok-punc">;</span></div>
<div class="console" id="roConsole"></div>
</div>
<div class="code-window">
<div class="code-topbar">
<div class="code-dots"><span class="code-dot r"></span><span class="code-dot y"></span><span class="code-dot g"></span></div>
<span class="code-filename">labeled.ts</span>
</div>
<div class="code-body"><span class="tok-cmt">// labeled elements — names show up in editor hints</span>
<span class="tok-kw">let</span> <span class="tok-var">range</span><span class="tok-punc">:</span> <span class="tok-punc">[</span><span class="tok-var">start</span><span class="tok-punc">:</span> <span class="tok-type">number</span><span class="tok-punc">,</span> <span class="tok-var">end</span><span class="tok-punc">:</span> <span class="tok-type">number</span><span class="tok-punc">]</span> <span class="tok-punc">=</span> <span class="tok-punc">[</span><span class="tok-num">0</span><span class="tok-punc">,</span> <span class="tok-num">100</span><span class="tok-punc">];</span></div>
</div>
<div class="code-window">
<div class="code-topbar">
<div class="code-dots"><span class="code-dot r"></span><span class="code-dot y"></span><span class="code-dot g"></span></div>
<span class="code-filename">rest.ts</span>
</div>
<div class="code-body"><span class="tok-cmt">// rest element — fixed first slot, open-ended remainder</span>
<span class="tok-kw">let</span> <span class="tok-var">scores</span><span class="tok-punc">:</span> <span class="tok-punc">[</span><span class="tok-type">string</span><span class="tok-punc">,</span> <span class="tok-punc">...</span><span class="tok-type">number</span><span class="tok-punc">[]]</span> <span class="tok-punc">=</span> <span class="tok-punc">[</span><span class="tok-str">"Alice"</span><span class="tok-punc">,</span> <span class="tok-num">90</span><span class="tok-punc">,</span> <span class="tok-num">85</span><span class="tok-punc">,</span> <span class="tok-num">100</span><span class="tok-punc">];</span></div>
</div>
</div>
<div class="tab-panel" id="t3">
<div class="code-window">
<div class="code-topbar">
<div class="code-dots"><span class="code-dot r"></span><span class="code-dot y"></span><span class="code-dot g"></span></div>
<span class="code-filename">operations.ts</span>
<button class="run-btn" id="opsBtn" type="button">
<svg viewBox="0 0 24 24" fill="currentColor"><polygon points="6 3 20 12 6 21 6 3"/></svg>
run
</button>
</div>
<div class="code-body"><span class="tok-kw">let</span> <span class="tok-var">point</span><span class="tok-punc">:</span> <span class="tok-punc">[</span><span class="tok-type">number</span><span class="tok-punc">,</span> <span class="tok-type">number</span><span class="tok-punc">]</span> <span class="tok-punc">=</span> <span class="tok-punc">[</span><span class="tok-num">10</span><span class="tok-punc">,</span> <span class="tok-num">20</span><span class="tok-punc">];</span>
<span class="tok-kw">let</span> <span class="tok-var">x</span> <span class="tok-punc">=</span> <span class="tok-var">point</span><span class="tok-punc">[</span><span class="tok-num">0</span><span class="tok-punc">];</span> <span class="tok-cmt">// access by index</span>
<span class="tok-kw">let</span> <span class="tok-var">y</span> <span class="tok-punc">=</span> <span class="tok-var">point</span><span class="tok-punc">[</span><span class="tok-num">1</span><span class="tok-punc">];</span>
<span class="tok-var">point</span><span class="tok-punc">[</span><span class="tok-num">0</span><span class="tok-punc">]</span> <span class="tok-punc">=</span> <span class="tok-num">15</span><span class="tok-punc">;</span> <span class="tok-cmt">// reassign an element</span>
<span class="tok-kw">let</span> <span class="tok-punc">[</span><span class="tok-var">px</span><span class="tok-punc">,</span> <span class="tok-var">py</span><span class="tok-punc">]</span> <span class="tok-punc">=</span> <span class="tok-var">point</span><span class="tok-punc">;</span> <span class="tok-cmt">// destructure</span>
<span class="tok-var">console</span><span class="tok-punc">.</span><span class="tok-var">log</span><span class="tok-punc">(</span><span class="tok-var">point</span><span class="tok-punc">.</span><span class="tok-var">length</span><span class="tok-punc">);</span> <span class="tok-cmt">// length is fixed</span>
<span class="tok-kw">let</span> <span class="tok-var">scores</span><span class="tok-punc">:</span> <span class="tok-punc">[</span><span class="tok-type">string</span><span class="tok-punc">,</span> <span class="tok-punc">...</span><span class="tok-type">number</span><span class="tok-punc">[]]</span> <span class="tok-punc">=</span> <span class="tok-punc">[</span><span class="tok-str">"Alice"</span><span class="tok-punc">,</span> <span class="tok-num">90</span><span class="tok-punc">,</span> <span class="tok-num">85</span><span class="tok-punc">,</span> <span class="tok-num">100</span><span class="tok-punc">];</span>
<span class="tok-kw">let</span> <span class="tok-punc">[</span><span class="tok-var">name</span><span class="tok-punc">,</span> <span class="tok-punc">...</span><span class="tok-var">rest</span><span class="tok-punc">]</span> <span class="tok-punc">=</span> <span class="tok-var">scores</span><span class="tok-punc">;</span> <span class="tok-cmt">// destructure with rest</span></div>
<div class="console" id="opsConsole"></div>
</div>
</div>
<script>
(function () {
var wrapper = document.currentScript.closest('.infographic-ts')
|| document.querySelector('.infographic-ts');
var root = wrapper;
var tabBtns = root.querySelectorAll('.tab-btn');
var panels = root.querySelectorAll('.tab-panel');
tabBtns.forEach(function (btn) {
btn.addEventListener('click', function () {
var target = btn.getAttribute('data-tab');
tabBtns.forEach(function (b) { b.classList.toggle('active', b === btn); });
panels.forEach(function (p) { p.classList.toggle('active', p.id === target); });
});
});
function line(consoleEl, cls, text) {
var el = document.createElement('div');
el.className = 'console-line ' + (cls || '');
el.textContent = text;
consoleEl.appendChild(el);
}
var roBtn = root.querySelector('#roBtn');
var roConsole = root.querySelector('#roConsole');
roBtn.addEventListener('click', function () {
roConsole.innerHTML = '';
roConsole.classList.add('show');
line(roConsole, 'err', "Error: Cannot assign to '0' because it is a read-only property.");
});
var opsBtn = root.querySelector('#opsBtn');
var opsConsole = root.querySelector('#opsConsole');
opsBtn.addEventListener('click', function () {
opsConsole.innerHTML = '';
opsConsole.classList.add('show');
line(opsConsole, '', 'x \u2192 10');
line(opsConsole, '', 'y \u2192 20');
line(opsConsole, '', 'point (after) \u2192 [15, 20]');
line(opsConsole, '', 'px, py \u2192 15, 20');
line(opsConsole, '', 'point.length \u2192 2');
line(opsConsole, '', 'name \u2192 "Alice"');
line(opsConsole, 'ok', 'rest \u2192 [90, 85, 100]');
});
})();
</script>
</div>⚠ Tuple vs array
Feature | Tuple | Array |
|---|---|---|
Length | Fixed (or known optional parts) | Variable |
Types | Can vary by position | Usually all elements same type |
Example | [string, number] | string[] |
✨ Summary
Tuple type | Example |
|---|---|
[string, number] | ["Alice", 30] |
[number, number, number?] | [10, 20] |
[boolean, ...string[]] | [true, "a", "b"] |