TypeScript: TypeScript Arrays and Tuples
Last updated: 2026-08-26
Arrays and tuples are the two most commonly used collection types in TypeScript—an array is a "collection of values of the same type," while a tuple is a special type of array with a "fixed length and specific types for each element."
1. Array Types
(1) Two Annotation Syntaxes
TypeScript has two equivalent ways to write array types:
TYPESCRIPT
// Method 1:Type + square brackets(Recommendations,More intuitive)
let numbers: number[] = [1, 2, 3, 4, 5];
let names: string[] = ["Charlie", "Diana", "Eric"];
// Method 2:Generic Arrays(Commonly used in generic scenarios)
let scores: Array<number> = [90, 85, 95];
let items: Array<string> = ["a", "b", "c"];
📌 Recommendation: Use the
type[] syntax for everyday development—it’s more concise. The generic syntax Array<T> is clearer when dealing with certain complex types or when used with generic functions.
(2) Array Type Inference
TYPESCRIPT
let arr1 = [1, 2, 3]; // Inferred as number[]
let arr2 = ["a", "b", "c"]; // Inferred as string[]
let arr3 = [1, "hello", true]; // Inferred as (number | string | boolean)[]
let arr4 = []; // Inferred as any[](Danger!)
🔥 Common Mistake: An empty array
[] is inferred as any[], and subsequent assignments of different types will not result in an error. In strict mode, it is recommended to explicitly label it as let arr4: number[] = [].
(3) Multidimensional Arrays
TYPESCRIPT
let matrix: number[][] = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
// Accessing Elements
console.log(matrix[0][1]); // 2
// Three-dimensional array
let cube: number[][][] = [[[1]]];
▶ Example: Basic Array Operations
Output:
TEXT
📖 Display only
Average Score: 87.6
Subject with the Highest Score: English (95pts)
TYPESCRIPT
let fruits: string[] = ["Apple", "Banana", "Orange"];
// Add an element
fruits.push("Grapes"); // Add at the end
fruits.unshift("Strawberries"); // Add at the beginning
// Delete Element
let last = fruits.pop(); // Delete the end,Back "Grapes"
let first = fruits.shift(); // Delete the beginning,Back "Strawberries"
// Search
let index = fruits.indexOf("Banana"); // 0(The strawberries and grapes were removed.,The banana came in first)
// Iterate
fruits.forEach((fruit, i) => {
console.log(`${i}: ${fruit}`);
});
Output:
TEXT
📖 Display only
0: Banana
1: Orange
2. Read-Only Arrays
Read-only arrays cannot be modified—adding, deleting, or modifying elements is not allowed:
(1) readonly modifier
TYPESCRIPT
let readonlyArr: readonly number[] = [1, 2, 3];
// readonlyArr[0] = 10; // ❌ Read-only,Cannot be modified
// readonlyArr.push(4); // ❌ Read-only,Cannot be added
// readonlyArr.length = 0; // ❌ Read-only,The length cannot be changed
let normalArr: number[] = [1, 2, 3];
readonlyArr = normalArr; // ✅ A regular array can be assigned to a read-only array
// normalArr = readonlyArr; // ❌ A read-only array cannot be assigned to a regular array.
(2) ReadonlyArray Generic
TYPESCRIPT
let readonlyArr2: ReadonlyArray<string> = ["a", "b", "c"];
// and readonly string[] Equivalent
💡 Purpose: Using a read-only array as a function parameter clearly tells the caller, "This function will not modify your array":
TYPESCRIPT
function printItems(items: readonly string[]) {
items.forEach(item => console.log(item));
// items.push("new"); // ❌ Compilation Error——The function is guaranteed not to be modified
}
let myItems = ["a", "b"];
printItems(myItems); // Safety——myItems Will not be modified
3. Tuple Type
A tuple is an array with "fixed length and specific types for each element"—it can be thought of as a lightweight version of a "named fixed structure."
(1) Basic Syntax
TYPESCRIPT
// Defining Tuples:[Type1, Type2, ...]
let user: [string, number] = ["Charlie", 20];
// Access by Index
console.log(user[0]); // "Charlie"(string Type)
console.log(user[1]); // 20(number Type)
// Assignments must match in type and length
// user = [20, "Charlie"]; // ❌ Type order does not match
// user = ["Charlie"]; // ❌ Not long enough
// user = ["Charlie", 20, true]; // ❌ Exceeds the length limit
(2) The Difference Between Tuples and Arrays
| Feature | Array number[] |
Tuple [string, number] |
|---|---|---|
| Length | Any | Fixed |
| Element Type | All the Same | Can Vary by Position |
| Access | All elements are of the same type | Each index has a specific type |
| Use Cases | Similar Data Sets | Small datasets with a fixed structure |
(3) Tuple Destructuring
TYPESCRIPT
let pair: [string, number] = ["Apple", 5];
let [fruit, count] = pair;
console.log(fruit); // "Apple"
console.log(count); // 5
// Including remaining elements
let record: [string, number, ...boolean[]] = ["Test", 100, true, false, true];
let [name, score, ...flags] = record;
console.log(name); // "Test"
console.log(score); // 100
console.log(flags); // [true, false, true]
(4) Optional Elements
Optional elements in a tuple can be marked with ?:
TYPESCRIPT
let result: [string, number?] = ["Success"];
console.log(result[0]); // "Success"
console.log(result[1]); // undefined(Optional elements may be omitted.)
⚠️ Note: Optional elements can only appear at the end.
[string?, number] is invalid—no required elements can follow an optional element.
(5) Tagged tuples
TypeScript 4.0 introduced tuple labels, which make the semantics of each position clearer:
TYPESCRIPT
let user: [name: string, age: number] = ["Charlie", 20];
let point: [x: number, y: number, z?: number] = [1.0, 2.5];
// Tags are only for document purposes,Does not affect the type——But the code's readability has improved significantly
function getRange(): [min: number, max: number] {
return [0, 100];
}
let [min, max] = getRange();
console.log(`Scope:${min} - ${max}`); // Scope:0 - 100
▶ Example: Tuples as function return values
TYPESCRIPT
// Tuples are ideal for representing the return values of functions."Multiple values"
function divide(a: number, b: number): [quotient: number, remainder: number] {
return [Math.floor(a / b), a % b];
}
let [quotient, remainder] = divide(17, 5);
console.log(`Quotient:${quotient},Remainder:${remainder}`); // Quotient:3,Remainder:2
// A tuple represents a key-value pair
function entries(obj: Record<string, number>): [string, number][] {
return Object.entries(obj) as [string, number][];
}
let scores = { Chinese Language: 90, Mathematics: 95, English: 88 };
for (let [subject, score] of entries(scores)) {
console.log(`${subject}:${score}pts`);
}
Output:
TEXT
📖 Display only
Quotient:3,Remainder:2
Chinese Language:90pts
Mathematics:95pts
English:88pts
4. Higher-Order Operations on Arrays
(1) Union-Typed Arrays vs. Arrays of Union Types
TYPESCRIPT
// Union Type Arrays:Each element in the array can be number or string
let mixed: (number | string)[] = [1, "two", 3, "four"];
// Union Types for Arrays:Either... or number[],Either... or string[]
let uniform: number[] | string[] = [1, 2, 3]; // ✅
uniform = ["a", "b", "c"]; // ✅
// uniform = [1, "two"]; // ❌ Do not mix
🔥 Common Mistake:
(number | string)[] and number[] | string[] have completely different meanings! The former refers to a "mixed array," while the latter refers to a "pure numeric array or pure string array."
(2) Type Safety of Array Methods
TYPESCRIPT
let nums: number[] = [3, 1, 4, 1, 5];
// sort An explicit comparison function is required,Otherwise, sort by string
nums.sort((a, b) => a - b); // ✅ Number Sorting:[1, 1, 3, 4, 5]
// map Automatic Inference of Return Types
let doubled = nums.map(n => n * 2); // Inferred as number[]
let asStrings = nums.map(String); // Inferred as string[]
// filter Automatically Infer Element Types
let big = nums.filter(n => n > 2); // Inferred as number[]
(3) Array Unpacking and Types
TYPESCRIPT
let a: number[] = [1, 2];
let b: number[] = [3, 4];
let merged: number[] = [...a, ...b]; // [1, 2, 3, 4]
// Tuple Unpacking
let prefix: [string, number] = ["No.", 0];
let full: [string, number, ...number[]] = [...prefix, 1, 2, 3];
// full = ["No.", 0, 1, 2, 3]
5. Choices in Actual Development
(1) When to Use Arrays
- Collections of similar data (user lists, score lists, configuration item lists)
- Uncertain number of elements
- Operations such as traversal, searching, and sorting are required
(2) When to Use Tuples
- Small data sets with fixed lengths and fixed structures (coordinates
[x, y], key-value pairs[key, value]) - Functions return multiple values
- Simple structures with only two or three elements (use objects or interfaces for more complex ones)
(3) When to Use a Read-Only Array
- Function parameters—a promise not to modify the passed-in array
- Constant Configuration—Preventing Accidental Changes
- API return value—informs the user that the data is immutable
▶ Example: Comprehensive Exercise—Student Grade Management
TYPESCRIPT
// Represented as a tuple [Subject, Fractions]
type Score = [subject: string, score: number];
// Storing Multiple Grades in an Array
let scores: Score[] = [
["Chinese Language", 92],
["Mathematics", 88],
["English", 95],
["Physics", 78],
["Chemistry", 85]
];
// Calculate the average score
function average(scores: readonly Score[]): number {
let total = scores.reduce((sum, [, score]) => sum + score, 0);
return total / scores.length;
}
// Find the subject with the highest score
function topSubject(scores: readonly Score[]): Score {
return scores.reduce((best, current) =>
current[1] > best[1] ? current : best
);
}
console.log("Average Score:" + average(scores).toFixed(1));
let [subject, score] = topSubject(scores);
console.log(`Subject with the Highest Score:${subject}(${score}pts)`);
Output:
TEXT
📖 Display only
Average Score:87.6
Subject with the Highest Score:English(95pts)
❓ FAQ
Q What is the difference between tuples and regular objects? When should each be used?
A Tuples are accessed by index (
tuple[0]), while objects are accessed by key (obj.name). Tuples are suitable for simple, fixed structures with 2–3 elements (such as coordinates or key-value pairs); use objects or interfaces when there are more than 3 elements or the semantics are complex, because user.name is much more readable than user[0].Q What exactly is the difference between (number | string)[] and number[] | string[]?
A
(number | string)[] is an array where “each element can be either a number or a string”—allowing for a mix, such as [1, "a", 2]. number[] | string[] is an array where “the entire array is either all numbers or all strings”—mixed types are not allowed, so [1, "a"] is invalid. The latter is a union of two array types, not a union-type array.Q What is the assignment relationship between
readonly number[] and number[]?A
number[] can be assigned to readonly number[] (tightening the type is safe), but readonly number[] cannot be assigned to number[] (loosening the type would result in the loss of read-only protection). This is similar to the assignment direction for const—it can only go from less strict to stricter.Q Why aren’t tuple push/pop operations type-checked?
A This is a known design flaw in TypeScript. Out-of-bounds element access in tuples (such as
tuple[100]) will throw an error, but the push/pop methods can be executed in strict mode without being type-checked. It is recommended to use readonly tuples (readonly [string, number]) to completely prevent modification.📖 Summary
- There are two ways to write array types:
type[](recommended) andArray<type>; they have exactly the same effect. readonly type[]andReadonlyArray<type>create read-only arrays; you cannot add, delete, or modify elements in them.- A tuple
[type1, type2, ...]is a special type of array with a fixed length, where each element is of a specific type. - Tuples support destructuring, optional elements (
type?), rest elements (...type[]), and labels ([name: string]) (A | B)[](union-type array) andA[] | B[](array of union types) have completely different meanings
📝 Exercises
- Basic Problem (Difficulty ⭐): Create an array
string[]to store the names of five programming languages, then useforEachto iterate through and print them. Next, write a read-only versionreadonly string[], try modifying it, and observe the error message. - Advanced Problem (Difficulty ⭐⭐): Define a function
swap(tuple: [string, number]): [number, string]using a tuple to swap the positions and types of the two elements in the tuple. For example,swap(["hello", 42])returns[42, "hello"]. - Challenge Problem (Difficulty ⭐⭐⭐): Implement a function
parseCSV(lines: string[]): [header: string[], ...rows: string[][]]that parses a CSV text file into tuples—where the first line is the header and the remaining lines are the data. The return type should be a tagged tuple with the remaining elements.