26

In a TypeScript file, I have defined a 3D array:

var myArr = ['one', [[19, 1], [13, 1], [86, 1], [12, 2]],
             'two',    [[83, 1], [72, 1], [16, 2]],
             'three',  [[4, 1]]];

function testArray(){
    console.log(myArr[1].length);
}

I get a warning under the length property:

Property 'length' does not exist on type '{}'

Is there something I can do to remove this warning?

Mel
  • 5,837
  • 10
  • 37
  • 42
RaelB
  • 3,301
  • 5
  • 35
  • 55
  • Works fine, perhaps your error is elsewhere. http://jsfiddle.net/yxrufk86/ – Omri Aharon Nov 23 '14 at 13:30
  • I think that it's because you are mixing strings and arrays, and although both have a `length` property, there is no common interface for that, so the type of the array is an array of objects. – Guffa Nov 23 '14 at 13:34
  • @ Omri: Yes the code does work ok. It is not an error. It is just a warning, but it hinders development because it is a "false" warning and I can't get rid of it... – RaelB Nov 23 '14 at 14:00
  • @ Guffa: If I replace the strings with numbers I get the same warning message. – RaelB Nov 23 '14 at 14:01

5 Answers5

29

I read a similar post here: How can I stop "property does not exist on type JQuery" syntax errors when using Typescript?

Which explains that I can cast to <any>.

This worked for me:

function testArray(){
    console.log((<any>myArr[1]).length);
}
Community
  • 1
  • 1
RaelB
  • 3,301
  • 5
  • 35
  • 55
10

Option 1: upgrade to bleeding-edge compiler and get union types

Option 2: Add a type annotation to the variable declaration:

var myArr: any[] = ['one', [[19, 1], [13, 1], [86, 1], [12, 2]],
             'two',    [[83, 1], [72, 1], [16, 2]],
             'three',  [[4, 1]]];

function testArray(){
    console.log(myArr[1].length);
}
Ryan Cavanaugh
  • 209,514
  • 56
  • 272
  • 235
8

The Object.values() method returns an array of a given object's own enumerable property values, in the same order as that provided by a for...in loop. (The only difference is that a for...in loop enumerates properties in the prototype chain as well.)

Object.values(myArr).length

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Object/values

LoneExile
  • 151
  • 1
  • 5
2

i faced this error before,you have to cast the type to any and when you use generics you have to extends.

check the example blow:

const result = <T extends any>(arr:T[]):T => {
  return arr[arr.length - 1] 
}

result([1,2,3])
RamTn
  • 99
  • 5
0

for those who already have a interface/type/class configured and would like it to have a length or something else i have a suggestion that i use. Inside the class, interface, type put the code below. It will set unknown only on undefined attributes. It is not necessary to put it at the end, I also suggest that you create a separate interface and extend it to your objects if you prefer

export interface x {
...
[props: string]: unknown 
...
}

This will make it possible for you to use any attribute name in your object, as bad as it sounds, it actually isn't. That's because for each unknown attribute you will be forced(T.S 4.4+) to do a forced conversion to some other type when you use, eg

(object.length as number). 

When analyzing the possible type of the attribute you will be more careful and will not try to access something that does not exist. Don't worry about your object auto-completion, it will keep working normally

Mithsew
  • 1,129
  • 8
  • 20