369

As far as I know a property's type can be defined in two ways when it's an Array.

property_name: type

where type can be either

Array<string>, Array<MyType>, etc. (e.g. let prop1: Array<string>)

and

string[], MyType[], etc. (e.g. let prop1: string[])

What is the difference between the two cases? Or am I misunderstanding something (perhaps something about <> used in casting?)

EDIT since the question is marked as duplicate, I am aware there is the other question about any[] but still I had a look at it before posting and to me it was more about the type 'any' than the different [] VS <> I asked

mark_h
  • 5,233
  • 4
  • 36
  • 52
dragonmnl
  • 14,578
  • 33
  • 84
  • 129
  • 5
    Possible duplicate of [Typescript Array vs any\[\]](http://stackoverflow.com/questions/15860715/typescript-array-vs-any) – Nitzan Tomer Apr 25 '16 at 13:39
  • 1
    They are practically the same constructs, and are effectively the same objects at runtime. [Reflect-metadata](https://github.com/rbuckton/ReflectDecorators) will also treat them both as having the `Array` object as their constructor. See the above linked answer. – John Weisz Apr 25 '16 at 13:43
  • 5
    @NitzanTomer that question is out-of-date -- `Array` didn't exist back then. – Nathan Shively-Sanders Apr 25 '16 at 17:14
  • @NathanShively-Sanders the answer is the same with or without the generics because this question can be reduced to "what's the different between `let x: Array;` to `let x: any[];`" – Nitzan Tomer Apr 25 '16 at 17:25

2 Answers2

419

There isn't any semantic difference

There is no difference at all. Type[] is the shorthand syntax for an array of Type. Array<Type> is the generic syntax. They are completely equivalent.

The handbook provides an example here. It is equivalent to write:

function loggingIdentity<T>(arg: T[]): T[] {
    console.log(arg.length);
    return arg;
}

Or:

function loggingIdentity<T>(arg: Array<T>): Array<T> {
    console.log(arg.length);
    return arg;
}

And here is a quote from some release notes:

Specifically, number[] is a shorthand version of Array<number>, just as Date[] is a shorthand for Array<Date>.

About the readonly type modifier

TypeScript 3.4, introduces the readonly type modifier. With a precision:

the readonly type modifier can only be used for syntax on array types and tuple types

let err2: readonly Array<boolean>; // error!    
let okay: readonly boolean[]; // works fine

The following declaration is equivalent to readonly boolean[]:

let okay2: ReadonlyArray<boolean>;
Paleo
  • 21,831
  • 4
  • 65
  • 76
  • thank you for the answer. could you please clarify what is exactly the in loggingIdentity? – dragonmnl Apr 25 '16 at 14:59
  • 3
    @dragonmnl, It is a generic type. Just read the section "Hello World of generics" in [the Handbook](http://www.typescriptlang.org/docs/handbook/generics.html). – Paleo Apr 25 '16 at 15:55
  • I think we're all agreed there is no functional difference, but has there been any recommendation on what is the preferred style? – chrismarx Oct 09 '17 at 15:38
  • 12
    There isn't an official recommendation. I personally use the shorthand and only the shorthand (`type[]`), because it is easier to read. – Paleo Oct 09 '17 at 16:26
  • 1
    I like to look at Angular's official style guide for guidance on these sorts of things. https://angular.io/guide/styleguide Secondly, I look at the Angular Material code base. https://github.com/angular/components **References to array as: `Array`**: styleguide: 0 ng-material: 35 **References to array as: `type[]`**: styleguide: 2 ng-material: 532 So for myself, I'd go for `type[]`, since it's what the Angular team seem to lean towards. – RonanCodes Aug 25 '19 at 12:16
  • 15
    They aren't _completely_ identical anymore: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#caveats – DShook Sep 23 '19 at 18:25
  • 1
    Also, TSLint may be configured to only allow the `T[]` notation if `T` is a _simple_ type, and require the `Array` notation if `T` is a complex type: https://palantir.github.io/tslint/rules/array-type/ – stemadsen Oct 18 '19 at 08:34
  • 6
    If I got it right, in `readonly` case it's not actually required. If you prefer a long notation you can write it like this: `let err2: ReadonlyArray;` – n4nn31355 Jun 06 '20 at 23:19
  • 3
    @n4nn31355 I think so. I edited to add this notice. – Paleo Jun 07 '20 at 17:38
  • 1
    Array came first and is backwards compatible with older typescript versions. Not that I can think of any reason you would want to move backwards with Typescript. – TamusJRoyce Feb 08 '21 at 03:47
  • Another difference is that T[] cannot be used as a base interface. – Joald Dec 13 '22 at 12:55
  • Cool think is also to look at how google have defined this standard: https://google.github.io/styleguide/tsguide.html#arrayt-type – Patryk Janik Jan 30 '23 at 17:59
8

There is a difference when you are defining fixed length arrays. You can't define a fixed length array with Array<>, you have to use the shorthand syntax:

const myFunc1 = (arg: [string, number, boolean]) => {
  console.log(arg);
};
myFunc1(["hello world", 123, true]);

// error: TS2314: Generic type 'Array ' requires 1 type argument(s).
const myFunc2 = (arg: Array<string, number, boolean>) => {
  console.log(arg);
};
myFunc2(["hello world", 123, true])

etoxin
  • 4,908
  • 3
  • 38
  • 50
  • 3
    Its also called tuples https://www.typescriptlang.org/docs/handbook/2/objects.html#tuple-types was going to write that its not a fixed size array, but it actually is, still definition is IMO misleading. Fixed size array would look like `const arr = new Array(3);`, though technically it will not be fixed ofc – Soul_man Nov 30 '22 at 17:52