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!
CodePudding user response:
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[]>>>