I’ve been trying to get these types working for a while now. Don’t worry about the implementation. I only want to fix the types. The function takes and reduces over the config array using the fn
property. Each config item should have the aggregated return type from the previous steps passed the fn
function. The types work, but the autocomplete in the editor is broken when I create a new object in the array, TS Server thinks it’s an array type. Can this be fixed?
Code:
interface Config<T extends object, R extends object> {
fn: (state: T) => R
bro?: boolean
}
interface Config<T extends object, R extends object> {
fn: (state: T) => R
bro?: boolean
}
interface OverloadRunner {
<A extends object = object, B extends object = object>(
configArray: [Config<A, B>],
): void
<
A extends object = object,
B extends object = object,
C extends object = object,
>(
configArray: [Config<A, B>, Config<A & B, C>],
): void
<
A extends object = object,
B extends object = object,
C extends object = object,
D extends object = object,
>(
configArray: [Config<A, B>, Config<A & B, C>, Config<A & B & C, D>],
): void
// extend for further items
}
const overloadRunner: OverloadRunner = (steps: Config<any, any>[]) => {
let accumulator = {}
for (const step of steps) {
const result = step.fn(accumulator)
accumulator = {
...accumulator,
...result,
}
}
}
// Usage example
overloadRunner([
{
fn: (state) => {
return { now: 'here' }
},
bro: false,
},
{
fn: (state) => {
return { next: 'step' } // state type correctly inferred as { now: string }
},
bro: false,
},
{
// does not autocomplete here. TS Server thinks it's an array
}
])
I tried moving the generic declarations to the entire interface and not the overloads. This looses the piping aspect of the state
arg
interface OverloadRunner<
A extends object = object,
B extends object = object,
C extends object = object,
D extends object = object,
> {
(configArray: [Config<A, B>]): void
(configArray: [Config<A, B>, Config<A & B, C>]): void
(configArray: [Config<A, B>, Config<A & B, C>, Config<A & B & C, D>]): void
}
I’ve tried using some tuple utility types, but they also didn’t fix autocomplete.
type StepsArray<
T extends any[],
R extends object = RequestPropertiesAndHelpers,
> = T extends [infer First extends object, ...infer Rest]
? [Step<R, First>, ...StepsArray<Rest, R & First>]
: []
Aaron Scherling is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.