Jamie Curnow
Jamie Curnow

Reputation: 794

In typescript is there a way to access the property of an interface property of type array?

I am writing a code generator to generate typescript based off of a JSON definition of a data structure. I am having an issue with accessing properties in object arrays within an interface.

Here is an example interface that poses the issue:

interface SomeComplexThing {
  propA: string
  propB: number
  propC: {
    propCA: Array<{
      propCA1: string
      propCA2: number
    }>
  }
  propD: SomeComplexThing['propC']['propCA']['propCA1'] // Error: Property 'propCA1' does not exist on type '{ propCA1: string; propCA2: number; }[]'
}

When trying to access SomeComplexThing['propC']['propCA']['propCA1'] I get the error:

Property 'propCA1' does not exist on type '{ propCA1: string; propCA2: number; }[]'

Now I know that I can access the property using an array index like this:

SomeComplexThing['propC']['propCA'][0]['propCA1']

Or even like this:

SomeComplexThing['propC']['propCA'][1234]['propCA1']

It seems odd to not be able to access the property inside this array type without having to reference it by some arbitrary number... When generating the code, I don't currently have the context to know that SomeComplexThing['propC']['propCA'] is an array type, so I can't add [0] in there as the type could just be an object.

Is there another way to write this in Typescript, or a Utility function of some kind that I could use to safely access the property without using the array index reference?

Upvotes: 2

Views: 1122

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 250336

As you discovered indexing an array type with a number will get you the item type. The more general approach is to index using the number type itself

propD: SomeComplexThing['propC']['propCA'][number]['propCA1'] 

Playground Link

Note: Indexing with a specific number vs the number type will produce the same result for arrays, but might produce different results for tuples, which do have a different type for each index value. Here indexing by number will get a union of all item types in the tuple

Upvotes: 4

Related Questions