В typescript есть ли способ получить доступ к свойству свойства интерфейса типа array?

#arrays #typescript #types #interface

#массивы #typescript #типы #интерфейс

Вопрос:

Я пишу генератор кода для генерации typescript на основе определения структуры данных в формате JSON. У меня возникла проблема с доступом к свойствам в массивах объектов в интерфейсе.

Вот пример интерфейса, который создает проблему:

 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; }[]'
}
  

При попытке доступа SomeComplexThing['propC']['propCA']['propCA1'] я получаю сообщение об ошибке:

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

Теперь я знаю, что могу получить доступ к свойству, используя индекс массива, подобный этому:

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

Или даже так:

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

Кажется странным, что невозможно получить доступ к свойству внутри этого типа массива без необходимости ссылаться на него каким-либо произвольным числом… При генерации кода у меня в настоящее время нет контекста, чтобы знать, что SomeComplexThing['propC']['propCA'] это тип массива, поэтому я не могу добавить [0] туда, поскольку тип может быть просто объектом.

Есть ли другой способ записать это в Typescript или какую-либо служебную функцию, которую я мог бы использовать для безопасного доступа к свойству без использования ссылки на индекс массива?

Ответ №1:

Как вы обнаружили, индексация типа массива с числом даст вам тип элемента. Более общий подход заключается в индексировании с использованием самого number типа

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

Ссылка на игровую площадку

Примечание: индексация с определенным номером в зависимости от типа number приведет к тому же результату для массивов, но может привести к разным результатам для кортежей, которые имеют разный тип для каждого значения индекса. Здесь индексация по number приведет к объединению всех типов элементов в кортеже