Is it possible to modify the code snippet below so that Test2
outputs: [string, boolean?, ...string[]]
while taking into account the optional field?
type Def = { type: any, spread: boolean, optional: boolean }
type A = { type: string, spread: false, optional: false }
type B = { type: boolean, spread: false, optional: true }
type C = { type: string[], spread: true, optional: false }
type D = { type: number, spread: false, optional: false }
type ArrayBuilder<
T extends Def[],
A extends any[] = [],
B extends any[] = [],
C extends any[] = [],
State extends 'A' | 'B' = 'A',
> = T extends [
infer H extends Def,
...infer R extends Def[],
] ? State extends 'A' ? H['spread'] extends true ? ArrayBuilder<R, A, H['type'], [], 'B'> : ArrayBuilder<R, [...A, H['type']], [], [], 'A'>
:ArrayBuilder<R, A, B, [...C, H['type']], 'B'>
: [...A, ...B, ...C]
type Test1 = ArrayBuilder<[A,C,D]> // [string, ...string[], number]
// Can the code above be modified, such that Test2 produces: [string, boolean?, ...string[]] by factoring in the optional field?
type Test2 = ArrayBuilder<[A,B,C]> // [string, boolean, ...string[]] - should become [string, boolean?, ...string[]]
To apply the spread, I'm using [...A,...ItemToSpread]
, but to apply the optional attribute, I must use {[I in keyof T]?: T[I] }
- which doesn't work well with spreads.