C.W.K.
Stream
Lesson 01 of 05 · published

Arrays: `T[]` and `Array<T>`

~9 min · arrays-tuples, arrays, generic-syntax

Level 0Curious
0 XP0/93 lessons0/23 achievements
0/100 XP to next level100 XP to go0% complete
"Two syntaxes, one type. Pick whichever reads more naturally for the case."

The two ways to spell an array type

TypeScript supports two equivalent syntaxes for array types: T[] (shorthand) and Array<T> (generic form). They produce the same type — the choice is style.

  • const ages: number[] = [21, 18, 16]
  • const ages: Array<number> = [21, 18, 16]

The shorthand reads naturally for simple element types: string[], number[], User[]. The generic form starts to win when the element type is itself a union or a complex compound: Array<string | number> reads more naturally than (string | number)[], where the parentheses are easy to misread.

Inference for array literals

TypeScript widens array element types from literals to their primitive parents by default:

  • ['hi', 'there'] infers string[] (not ('hi' | 'there')[]).
  • [1, 2, 3] infers number[].
  • [1, 'two'] infers (string | number)[] — the compiler unions the element types.

This widening is usually what you want. When you want the narrow inference, reach for as const (covered in lesson 5.4) or an explicit tuple annotation.

Array operations are typed

The whole Array prototype — map, filter, reduce, find, flat, etc. — has rich types in the standard library. The compiler tracks element types through chains. users.filter(u => u.active).map(u => u.email) on a User[] ends up as string[] automatically.

The one gotcha: methods that take a callback may need their generic explicit if the inference picks a wider type. Array.from(set) usually works, but for complex Iterable shapes you sometimes write Array.from<T>(iter).

The convention: prefer T[] for simple element types and Array<T> when the element type is a union or compound expression. Stay consistent within a file.

Multi-dimensional arrays

Stack the syntax for nested arrays. number[][] is an array of arrays of numbers. Array<Array<number>> is the same thing. For type readability, the shorthand is usually clearer for simple nesting; for complex nesting, you might extract a type alias.

Pippa's confession

cwkPippa's frontend uses T[] almost universally. The one place I switch to Array<T> is when T is a tagged union — Array<{ type: 'a'; payload: A } | { type: 'b'; payload: B }> reads better than the parenthesized shorthand. Otherwise, the shorthand is denser and easier to skim.

Code

Two syntaxes, inference, method chains·typescript
// Two syntaxes, equivalent.
const a: string[] = ['hi'];
const b: Array<string> = ['hi'];

// Choose by readability.
const easy: (string | number)[] = [];        // parens easy to miss
const clearer: Array<string | number> = [];  // intent obvious

// Inference widens to primitives:
const inferred = [1, 2, 3];                  // number[]
const mixed = [1, 'two'];                    // (string | number)[]
const withNull = [1, null];                  // (number | null)[]

// Method chains preserve element types.
const names = ['Pippa', 'Dad', 'Ttori'];
const lengths = names.map((n) => n.length).filter((l) => l > 3);
// names: string[]  → map yields number[]  → filter yields number[]
Multi-dimensional and generic·typescript
// Multi-dimensional, generic helpers.

const grid: number[][] = [
  [1, 2, 3],
  [4, 5, 6],
];

// Helpful aliases for common patterns.
type Pair<T> = [T, T];
type Matrix<T> = T[][];

// Array.from with explicit generic when inference is weak.
const fromSet = Array.from(new Set([1, 2, 3]));     // number[] — inferred
const fromMap = Array.from<[string, number]>(
  new Map([['a', 1], ['b', 2]]).entries(),
);                                                   // [string, number][] — explicit

External links

Exercise

Declare an array of User objects (where User is your existing interface). Now declare an array whose elements are either Users or Guest (a different shape). Compare the two syntaxes — which form do you prefer for each, and why?
Hint
Simple element type → shorthand. Union element type → generic form. Once you pick a default, stick with it; consistency is more valuable than micro-optimization on one line.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.