T[]
vs. Array<T>
in TypeScriptIn this blog post, we explore two equivalent notations for Arrays in TypeScript: T[]
and Array<T>
. I prefer the latter and will explain why.
T[]
vs. Array<T>
In TypeScript, there are two notations for an Array of strings:
string[]
Array<string>
Both notations are equivalent.
T[]
? Why are there two notations?
Array<T>
.T[]
was the only notation for Arrays.So it looks like TypeScript simply stuck with the status quo when version 0.9 came along: It still exclusively uses T[]
– e.g., when inferring types or even when displaying a type that was written Array<T>
.
Even though I have read once or twice that JSX is the cause of TypeScript’s preference, I don’t think that’s the case:
The Array<T>
notation is compatible with JSX: It only exists at the type level and can be used without any problems in .jsx
files.
JSX does, however, make one syntax impossible to use – type assertions via angle brackets:
// Not possible in .tsx files:
const value1 = <DesiredType>valueWithWrongType;
// Can be used everywhere:
const value2 = valueWithWrongType as DesiredType;
Array<T>
I find it often looks better – especially if constructs related to element types get more complicated:
// Array of tuples
type AT1 = Array<[string, number]>;
type AT2 = [string, number][];
// Array of union elements
type AU1 = Array<number | string>;
type AU2 = (number | string)[];
// Inferring type variables
type ExtractElem1<A> = A extends Array<infer Elem> ? Elem : never;
type ExtractElem2<A> = A extends (infer Elem)[] ? Elem : never;
// Readonly types
type RO1 = ReadonlyArray<unknown>;
type RO2 = readonly unknown[];
// `readonly` applies to `[]` not to `unknown`!
More reasons:
Array<T>
looks similar to Set<T>
and Map<K,V>
.T[]
can be confused with [T]
(tuples that have a single component whose type is T
) – especially by people new to TypeScript.const strArr = new Array<string>();
T[]
Because TypeScript always uses T[]
, code that uses that notation is more consistent with language tooling.
[]
in T[]
binds strongly The square brackets in T[]
bind strongly. Therefore, we need to parenthesize any type T
that consists of more than a single token – e.g. (line A, line B):
type ArrayOfStringOrNumber = (string | number)[]; // (A)
const Activation = {
Active: 'Active',
Inactive: 'Inactive',
} as const;
type ActivationKeys = (keyof typeof Activation)[]; // (B)
// ("Active" | "Inactive")[]
typescript-eslint has the rule array-type
for enforcing a consistent Array notation style. The options are:
T[]
Array<T>
T[]
for single-token T
; otherwise Array<T>