Question
I have an array like this:
[1, "message"]
How should I define its type in TypeScript?
Specifically, I want to understand how to type an array that contains values of different types, such as a number and a string.
Short Answer
By the end of this page, you will understand how TypeScript handles arrays with mixed value types, when to use a union-type array like (number | string)[], and when to use a tuple like [number, string]. You will also learn the practical difference between these two approaches, how they behave in real code, and how to avoid common typing mistakes.
Concept
In TypeScript, there are two common ways to describe an array containing multiple types:
- Union-type array: an array where each element can be one of several types
- Tuple: an array with a fixed length and fixed types at specific positions
For the value:
[1, "message"]
TypeScript could describe it in either of these ways depending on what you mean.
1. Union-type array
let values: (number | string)[] = [1, "message"];
This means:
- the array can contain numbers or strings
- elements can appear in any order
- the array can have any length
So all of these are valid:
let values: (number | string)[] = [1, "message", 2, "hello"];
2. Tuple
let pair: [number, string] = [1, "message"];
This means:
Mental Model
Think of these two types like different kinds of containers.
Union-type array: a basket
A union-type array is like a basket that can hold apples or oranges in any order.
(number | string)[]
You are saying:
- every item must be either a number or a string
- but you do not care which position each one is in
Tuple: a labeled tray
A tuple is like a tray with labeled slots:
- slot 1: number
- slot 2: string
[number, string]
You are saying:
- the first position has a specific meaning
- the second position has a specific meaning
- the structure must stay fixed
If your data is really a structured record packed into an array, a tuple is usually the better fit.
Syntax and Examples
Union-type array syntax
let items: (number | string)[] = [1, "message"];
This allows any number of elements, as long as each one is a number or a string.
let items: (number | string)[] = [1, "hello", 42, "world"];
Tuple syntax
let item: [number, string] = [1, "message"];
This means:
- index
0must be a number - index
1must be a string
Valid:
let item: [number, string] = [1, "message"];
Step by Step Execution
Consider this tuple example:
let pair: [number, string] = [1, "message"];
const first = pair[0];
const second = pair[1];
Step by step
- TypeScript sees this declaration:
let pair: [number, string]
This means the variable must contain:
- a number at index
0 - a string at index
1
- The assigned value is checked:
[1, "message"]
1matchesnumber"message"matchesstring
So the assignment is valid.
Real World Use Cases
When to use a tuple
Tuples are useful when an array represents a fixed structure.
Examples:
- Coordinate pairs
let point: [number, number] = [10, 20]; - Database row fragments
let userSummary: [number, string] = [1, "Alice"]; - Function return values
function getStatus(): [number, string] { return [200, "OK"]; } - Key-value pairs
let entry: [string, number] = ["age", 30];
When to use a union-type array
Union-type arrays are useful when the array is a general list of allowed values.
Real Codebase Usage
In real projects, developers often prefer the most precise type they can reasonably use.
Common pattern: tuples for structured return values
function parseLine(line: string): [number, string] {
const parts = line.split(":");
return [Number(parts[0]), parts[1]];
}
This is useful when a function always returns a fixed pair.
Common pattern: arrays of tuples
const users: [number, string][] = [
[1, "Alice"],
[2, "Bob"],
[3, "Charlie"]
];
This means each item in the outer array is a tuple.
Common pattern: validation before use
With union-type arrays, developers often narrow types before using them:
const values: (number | string)[] = [, ];
( value values) {
( value === ) {
.(value.());
} {
.(value.());
}
}
Common Mistakes
1. Using number[] | string[] when you mean mixed elements
Broken code:
let values: number[] | string[] = [1, "message"];
Why it is wrong:
number[] | string[]means either an array of only numbers or an array of only strings- it does not mean one array containing both
Correct:
let values: (number | string)[] = [1, "message"];
2. Using a union array when you actually need fixed positions
let pair: (number | string)[] = [1, "message"];
This works, but it is less specific than:
let pair: [number, ] = [, ];
Comparisons
| Type | Example | Meaning | Best Use Case |
|---|---|---|---|
| Union-type array | `(number | string)[]` | Any element can be a number or string |
| Tuple | [number, string] | First item is number, second is string | Fixed structure with known positions |
| Array union | `number[] | string[]` | Entire array is either all numbers or all strings |
| Object | { id: number, message: string } | Named fields instead of positions | Clearer structured data |
Quick comparison example
let a: (number | string)[] = [, , ];
: [, ] = [, ];
: [] | [] = [, , ];
Cheat Sheet
Mixed array types in TypeScript
// Flexible array with mixed allowed types
let values: (number | string)[] = [1, "message"];
// Fixed two-element tuple
let pair: [number, string] = [1, "message"];
Use this when...
-
Use
(number | string)[]when:- the array can have many elements
- order is not important for typing
- each element can be either type
-
Use
[number, string]when:- the array always has exactly two items
- each position has a specific type
Important difference
number[] | string[]
means:
- either all numbers
- or all strings
It does not mean mixed elements.
Type results
FAQ
How do I type an array with both numbers and strings in TypeScript?
Use a union-type array:
let values: (number | string)[] = [1, "message"];
How do I type exactly [number, string] in TypeScript?
Use a tuple:
let pair: [number, string] = [1, "message"];
What is the difference between (number | string)[] and [number, string]?
(number | string)[] is a flexible array where any element can be a number or a string.
[number, string] is a tuple with exactly two items in a fixed order.
Is number[] | string[] the same as (number | string)[]?
No.
number[] | string[]means the entire array is all numbers or all strings.
Mini Project
Description
Build a small TypeScript example that stores status results in two ways: as a flexible mixed-value array and as a fixed tuple. This helps you see when each type is appropriate and how TypeScript treats them differently when you read values.
Goal
Create and use both a union-type array and a tuple, then observe how TypeScript types the values you read from them.
Requirements
- Create one variable typed as
(number | string)[] - Create one variable typed as
[number, string] - Add valid values to both variables
- Read values from each variable and log them
- Use a
typeofcheck when working with the union-type array
Keep learning
Related questions
@Directive vs @Component in Angular: Differences, Use Cases, and When to Use Each
Learn the difference between @Directive and @Component in Angular, including use cases, examples, and when to choose each.
Angular (change) vs (ngModelChange): What’s the Difference?
Learn the difference between Angular (change) and (ngModelChange), when each fires, and which one to use in forms and inputs.
Angular Dependency Injection: Fix "Can't Resolve All Parameters for Component" Errors
Learn why Angular shows "Can't resolve all parameters for component" and how to fix service injection issues in components.