A tuple type such as {[number, number]} describes an array with exactly two elements, both numbers. Each position can have its own type, {[string, number]}, and TypeScript checks the length as well as the elements.
Tuples suit small fixed groups returned from a function, such as a minimum and maximum, or a key and a value. Elements can be named ([min: number, max: number]), optional (quantity?: number) and followed by a rest element (...values: number[]).
At a glance
| Use | JSDoc in a .js file | TypeScript in a .ts file |
|---|---|---|
| Fixed length | /** @type {[number, number]} */ | : [number, number] |
| Named elements | /** @returns {[min: number, max: number]} */ | (): [min: number, max: number] |
| Optional element | /** @type {[sku: string, quantity?: number]} */ | : [sku: string, quantity?: number] |
| Rest elements | /** @type {[label: string, ...values: number[]]} */ | : [label: string, ...values: number[]] |
Examples
/**
* @param {number[]} prices
* @returns {[min: number, max: number]}
*/
export function priceRange(prices) {
return [Math.min(...prices), Math.max(...prices)];
}
const [low, high] = priceRange([19.5, 12, 30]);
/** @type {[sku: string, quantity?: number]} */
const line = ["TEE-01"];
/** @type {[label: string, ...values: number[]]} */
const row = ["Sales", 120, 98, 143];
export { low, high, line, row };export function priceRange(prices: number[]): [min: number, max: number] {
return [Math.min(...prices), Math.max(...prices)];
}
const [low, high] = priceRange([19.5, 12, 30]);
const line: [sku: string, quantity?: number] = ["TEE-01"];
const row: [label: string, ...values: number[]] = ["Sales", 120, 98, 143];
export { low, high, line, row };jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} /** @type {[x: number, y: number]} */
const point = [10, 20, 30];error TS2322: Type '[number, number, number]' is not assignable to type '[x: number, y: number]'.
Source has 3 element(s) but target allows only 2.
export { point };jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} /** @param {number[]} prices */
function priceRange(prices) {
return [Math.min(...prices), Math.max(...prices)];
}
/** @type {[number, number]} */
const range = priceRange([19.5, 12]);error TS2322: Type 'number[]' is not assignable to type '[number, number]'.
Target requires 2 element(s) but source may have fewer.
export { range };jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": ["*.js"]
} An array literal is not a tuple
Without a type, return [min, max] is inferred as number[], an array of any length. Assigning that to a [number, number] fails (TS2322, "Target requires 2 element(s) but source may have fewer"), as the third example shows. Declare the tuple on the function with @returns {[number, number]}, or use a const assertion, which makes a read-only tuple.
Element names
Names in a tuple type are documentation: they appear in hovers and completions, and they do not change how you destructure the value. TypeScript added named tuple elements in version 4.0, and optional and rest elements in 3.0.
Gotchas
- Tuples are still mutable arrays:
range.push(3)passes. Make themreadonly [number, number]when that matters. - Past three or four elements, an object with named properties is easier to read than a tuple.
Questions
How do I return two values from a function with JSDoc types?
Return a tuple and declare it: @returns {[min: number, max: number]}. Callers destructure it, const [low, high] = priceRange(prices).
Sources
- Object Types: tuple types · TypeScript handbook
- TypeScript 4.0: labeled tuple elements · TypeScript release notes
- TypeScript 3.0: optional and rest elements in tuple types · TypeScript release notes
Last reviewed 20 October 2026.