Тип для функции объект массивов в массив объектов с ключом из объекта в начале

Есть функция на js.

export function aggregatedArrays2ObjectArray(schoolsData) {
  const entries = Object.entries(schoolsData);

  if (!entries || !entries[0] || !entries[1].length) return [];
  return entries[0][1].map((_, index) => {
    const dataToReturn = {};

    entries.forEach(([key, value]) => {
      dataToReturn[key] = value[index];
    });

    return dataToReturn;
  });
}

Эта функция делает из объекта

{
  name: ['name1', 'name2', 'name3'],
  otherkey: ['otherkey1', 'otherkey2', 'otherkey3']
}

В массив объектов

[
  {
    name: 'name1',
    otherkey: 'otherkey1'
  }, {
    name: 'name2',
    otherkey: 'otherkey2'
  }, {
    name: 'name3',
    otherkey: 'otherkey3'
  }
]

Нужно продумать верный тип для этой функции на typescript Пожалуйста, помогите разобраться

Спасибо


Ответы (2 шт):

Автор решения: ThisMan

Попробуйте так

type AggregatedArrays2ObjectArrayResult<T> = {
  [K in keyof T]: string
}

function aggregatedArrays2ObjectArray<T>(schoolsData: T): AggregatedArrays2ObjectArrayResult<T>[] {
  const entries = Object.entries(schoolsData);

  if (!entries || !entries[0] || !entries[1].length) return [];
  return entries[0][1].map((_: any, index: number) => {
    const dataToReturn: Record<string, string> = {};

    entries.forEach(([key, value]) => {
      dataToReturn[key] = value[index];
    });

    return dataToReturn;
  });
}

interface SchoolsData {
  name: string[];
  otherkey: string[];
}

const data: SchoolsData = {
  name: ['name1', 'name2', 'name3'],
  otherkey: ['otherkey1', 'otherkey2', 'otherkey3'],
}

const result = aggregatedArrays2ObjectArray<SchoolsData>(data);
result[0].otherkey; // OK
result[0].some // NOT OK 

[K in keyof T] - запись означает "Взять все ключи из типа T и использовать их, как ключи для нового типа".

Подробнее

→ Ссылка
Автор решения: qwabra
type base = { [k: string]: any[] };
type convertedList<T extends base> = { [k in keyof T]: T[k][0] }[];

declare function convert<T extends base>(base: T): convertedList<T>;
t1: {
    let arr = convert({
        name: ['name1', 'name2', 'name3'],
        otherkey: [1, 2, 3]
    })
    const {
        // const name: string
        name,
        // const otherkey: number
        otherkey
    } = arr[0]
}
t2: {
    let arr: convertedList<{ name: string[], otherkey: number[] }> = [
        {
            name: '',
            // otherkey: 'str' // Type 'string' is not assignable to type 'number'.(2322)
            otherkey: 1
        }, {
            name: '',
            otherkey: 3
        }
    ]
}
t3: {
    const base = { otherkey: [1, '2', [3]] }
    let arr: convertedList<typeof base> = [
        {
            // (property) otherkey: string | number | number[]
            otherkey: 1
        }
    ]
}
→ Ссылка