After experimenting with transforming arguments of a function using a recursive type, I encountered an issue trying to make the type work. To illustrate the problem, I created a simplified example along with examples using a mapped type (for this particular toy example, a mapped type would suffice): Playground
Initially, I created Transform functions using both mapped types and recursive types, with test data and tests to verify that they return the same result.
type TestItems = [string, number, string, boolean]
export type MappedTransform<UnionWith, Items extends any[]>
= { [I in keyof Items]: Items[I] | UnionWith }
type RecursiveTransform<UnionWith, Items extends any[]>
= Items extends [infer Head, ...infer Tail]
? [Head | UnionWith, ...RecursiveTransform<UnionWith, Tail>]
: [];
type mappedTypes = MappedTransform<undefined, TestItems>
type recursiveTypes = RecursiveTransform<undefined, TestItems>
Then, I implemented a function that utilizes the transform via a mapped type. I assumed that the UnionWith type would be passed as the first type argument, while the second argument would be filled with a tuple type containing the types of the function's arguments. This setup generates the correct type.
export const fnWithMappedType = <UnionWith extends any, Args extends any[]>
(data: UnionWith, ...args: MappedTransform<UnionWith, Args>) => {}
fnWithMappedType(undefined, "first", 42, true)
However, when I tried plugging the types into the recursive type transformer in the same way as above, the resulting type behaved differently in isolation compared to the test examples. It led to an empty tuple, causing the function to accept only the very first parameter instead of all four like in the previous example.
export const fnWithRecursiveType = <UnionWith extends any, Args extends any[]>
(data: UnionWith, ...args: RecursiveTransform<UnionWith, Args>) => {}
fnWithRecursiveType(undefined, "first", 42, true)
I'm wondering if there is some hidden caveat or if I missed something. Is there a way to solve this issue so that arguments can be transformed by the recursive type?