Search code examples
typescriptfunctiontypescript-typingsreturn-typenested-object

Get as many nested Records in returnType as the arguments passed to the function


What I am trying to achieve is typing a deeply nested ReturnType of a function, based on the number of arguments provided in the "rest" argument. For example, if we have:

getFormattedDates(
  dates: Date[],
  ...rest: string[] // ['AAA', 'BBB', 'CCC', etc...]
): Record<string, Record<string, Record<string,etc...>>>

The last nested object should be of type Record<string, Date[]>, while if there is no 2nd argument, the return type should be Date[].

So far I have tried googling various things, but I couldn't get a hold on such a type, and I would also like to understand the logic behind it.

This is my first question ever asked, so I hope it is explicit enough. :)

Hope someone can shed some light on this issue. Thanks!


Solution

  • You can build the type recursively:

    type ToRecord<T> = T extends [string, ...infer Rest]
        ? Record<string, ToRecord<Rest>>
        : Date[]
    
    declare function getFormattedDates<T extends string[]>(
        dates: Date[],
        ...rest: T // ['AAA', 'BBB', 'CCC', etc...]
    ): ToRecord<T>
    
    const p0 = getFormattedDates([]) // Date[]
    const p1 = getFormattedDates([], 'AAA') // Record<string, Date[]>
    const p3 = getFormattedDates([], 'AAA', 'BBB', 'CCC') // Record<string, Record<string, Record<string, Date[]>>>
    

    Playground