Завдання

Дано тип кортежу T, який містить лише рядки, і тип U. Створіть об’єкт рекурсивно.

type a = TupleToNestedObject<["a"], string>; // {a: string}
type b = TupleToNestedObject<["a", "b"], number>; // {a: {b: number}}
type c = TupleToNestedObject<[], boolean>; // boolean. if the tuple is empty, just return the U type

Розв’язок

Давайте почнемо з перебору кортежу, виводячи його вміст.

type TupleToNestedObject<T, U> = T extends [infer F, ...infer R]
  ? never
  : never;

Що робити, якщо Т порожній? У цьому випадку ми повертаємо тип U як є.

type TupleToNestedObject<T, U> = T extends [infer F, ...infer R] ? never : U;

Оскільки ключі для object можуть бути лише типу string, ми повинні перевірити, чи є F рядком.

type TupleToNestedObject<T, U> = T extends [infer F, ...infer R]
  ? F extends string
    ? never
    : never
  : U;

Якщо F це рядок, нам потрібно створити об’єкт і рекурсивно пройти решту кортежу. Таким чином ми пройдемо весь кортеж і створимо вкладені об’єкти, поки не дійдемо до останнього елементу, після чого ми просто повернемо U як його тип.

type TupleToNestedObject<T, U> = T extends [infer F, ...infer R]
  ? F extends string
    ? { [P in F]: TupleToNestedObject<R, U> }
    : never
  : U;

Посилання