306

I am creating simple logic game called "Three of a Crime" in TypeScript.

When trying to pre-allocated typed array in TypeScript, I tried to do something like this:

var arr = Criminal[];

which gave the error "Check format of expression term" .

also tried doing this

var arr : Criminal = [];

and this produced "cannot convert any[] to 'Criminal'

what is the 'TypeScript' way to do this?

c69
  • 19,951
  • 7
  • 52
  • 82
darethas
  • 7,377
  • 3
  • 23
  • 32

7 Answers7

410

The existing answers missed an option, so here's a complete list:

// 1. Explicitly declare the type
var arr: Criminal[] = [];

// 2. Via type assertion
var arr = <Criminal[]>[];
var arr = [] as Criminal[];

// 3. Using the Array constructor
var arr = new Array<Criminal>();
  1. Explicitly specifying the type is the general solution for whenever type inference fails for a variable declaration.

  2. The advantage of using a type assertion (sometimes called a cast, but it's not really a cast in TypeScript) works for any expression, so it can be used even when no variable is declared. There are two syntaxes for type assertions, but only the latter will work in combination with JSX if you care about that.

  3. Using the Array constructor is something that will only help you in this specific use case, but which I personally find the most readable. However, there is a slight performance impact at runtime*. Also, if someone were crazy enough to redefine the Array constructor, the meaning could change.

It's a matter of personal preference, but I find the third option the most readable. In the vast majority of cases the mentioned downsides would be negligible and readability is the most important factor.

*: Fun fact; at the time of writing the performance difference was 60% in Chrome, while in Firefox there was no measurable performance difference.

Community
  • 1
  • 1
Thorarin
  • 47,289
  • 11
  • 75
  • 111
264

The issue of correctly pre-allocating a typed array in TypeScript was somewhat obscured for due to the array literal syntax, so it wasn't as intuitive as I first thought.

The correct way would be

var arr : Criminal[] = [];

This will give you a correctly typed, empty array stored in the variable 'arr'

starball
  • 20,030
  • 7
  • 43
  • 238
darethas
  • 7,377
  • 3
  • 23
  • 32
28

I know this is an old question but I recently faced a similar issue which couldn't be solved by this way, as I had to return an empty array of a specific type.

I had

return [];

where [] was Criminal[] type.

Neither return: Criminal[] []; nor return []: Criminal[]; worked for me.

At first glance I solved it by creating a typed variable (as you correctly reported) just before returning it, but (I don't know how JavaScript engines work) it may create overhead and it's less readable.

For thoroughness I'll report this solution in my answer too:

let temp: Criminal[] = [];
return temp;

Eventually I found TypeScript type casting, which allowed me to solve the problem in a more concise and readable (and maybe efficient) way:

return <Criminal[]>[];

Hope this will help future readers!

Community
  • 1
  • 1
Fylax
  • 1,138
  • 2
  • 15
  • 24
7

Please try this which it works for me.

return [] as Criminal[];
Zhihong LU
  • 143
  • 1
  • 4
4

Okay you got the syntax wrong here, correct way to do this is:

var arr: Criminal[] = [];

I'm assuming you are using var so that means declaring it somewhere inside the func(),my suggestion would be use let instead of var.

If declaring it as c class property usse acces modifiers like private, public, protected.

Grayrigel
  • 3,474
  • 5
  • 14
  • 32
3

For publicly access use like below:

public arr: Criminal[] = [];
סטנלי גרונן
  • 2,917
  • 23
  • 46
  • 68
rk13
  • 79
  • 1
  • 5
0

TLDR:

// explicitly type the variable arr
var arr: Criminal[] = [];

In depth:

If we have an array with no elements like:

var arr = [];

TS has no way of knowing at compile time what will be in that array and the type of arr will be:

any[]

It is then the job of the programmer to tell TS the type of the array which can be done with a type annotation:

var arr: Criminal[] = [];

If we then were to get an element out of the array Typescript knows the element will be of type Criminal.

Willem van der Veen
  • 33,665
  • 16
  • 190
  • 155
  • I asked this question almost 10 years ago when I was in my last semester of college for my CS degree and typescript was still pre v1 and brand new to most people. It was for a PL research project for describing "new and esoteric programming languages" I just love that it's still relevant today, and apparently still applicable almost a decade later. – darethas Sep 02 '22 at 21:04