4.6 Array Literals

An array literal

  1. [ expr1, expr2, ..., exprN ]

denotes a value of an array type (section 3.3.2) or a tuple type (section 3.3.3) depending on context.

Each element expression in a non-empty array literal is processed as follows:

  • If the array literal contains no spread elements, and if the array literal is contextually typed (section 4.23) by a type T and T has a property with the numeric name N, where N is the index of the element expression in the array literal, the element expression is contextually typed by the type of that property.
  • Otherwise, if the array literal is contextually typed by a type T with a numeric index signature, the element expression is contextually typed by the type of the numeric index signature.
  • Otherwise, the element expression is not contextually typed.

The resulting type an array literal expression is determined as follows:

  • If the array literal is empty, the resulting type is an array type with the element type Undefined.
  • Otherwise, if the array literal contains no spread elements and is contextually typed by a tuple-like type (section 3.3.3), the resulting type is a tuple type constructed from the types of the element expressions.
  • Otherwise, if the array literal contains no spread elements and is an array assignment pattern in a destructuring assignment (section 4.21.1), the resulting type is a tuple type constructed from the types of the element expressions.
  • Otherwise, the resulting type is an array type with an element type that is the union of the types of the non-spread element expressions and the numeric index signature types of the spread element expressions.

A spread element must specify an expression of an array-like type (section 3.3.2), or otherwise an error occurs.

TODO: The compiler currently doesn’t support applying the spread operator to a string (to spread the individual characters of a string into a string array). This will eventually be allowed, but only when the code generation target is ECMAScript 2015 or later.

TODO: Document spreading an iterator into an array literal.

The rules above mean that an array literal is always of an array type, unless it is contextually typed by a tuple-like type. For example

  1. var a = [1, 2]; // number[]
  2. var b = ["hello", true]; // (string | boolean)[]
  3. var c: [number, string] = [3, "three"]; // [number, string]

When the output target is ECMAScript 3 or 5, array literals containing spread elements are rewritten to invocations of the concat method. For example, the assignments

  1. var a = [2, 3, 4];
  2. var b = [0, 1, ...a, 5, 6];

are rewritten to

  1. var a = [2, 3, 4];
  2. var b = [0, 1].concat(a, [5, 6]);