The aim is, from a tuple, to get all non optional (optional or rest) items of the tuple.
Everything works just fine, except for one detail: labels when tuple has rest items.
As those are retrieved for tuple without rest, with rest i loose the label information.
// Common types
type Tuple = ReadonlyArray <unknown>
type Tail <T extends Tuple> =
T extends [] ? T :
T extends [any?, ...infer R] ? R : T
type Length <T extends Tuple> = T ['length']
type Last <T extends Tuple> = T [Length <Tail <T>>]
// Tests
type Empty = [] // target: []
type OnlyReq = [a: 1, b: 2] // target: [a: 1, b: 2]
type WithOpt = [a: 1, b: 2, c?: 3, d?: 4] // target: [a: 1, b: 2]
type WithRest = [a: 1, b?: 2, ...c: 3 []] // target: [a: 1]
type test1 = StripOptionnals <Empty> // ok: []
type test2 = StripOptionnals <OnlyReq> // ok: [a: 1, b: 2]
type test3 = StripOptionnals <WithOpt> // ok: [a: 1, b: 2]
type test4 = StripOptionnals <WithRest> // need fix, label lost: [1]
// test4 is losing the label informations
// Type
export type StripOptionnals <T extends Tuple> =
T extends []
? []
: number extends T ['length']
? StripOptionnalsRestRec <T, []>
: StripOptionnalsRec <T>
// here we gather info for the required part of a tuple that have rest items
// but doing so we loose the labels info
type StripOptionnalsRestRec <T extends Tuple, Req extends Tuple> = // <- need fix
Partial <T> extends T
? Req
: T extends [infer Head, ...infer Rest]
? StripOptionnalsRestRec <Rest, [...Req, Head]>
: Req
// here all works, we take all non optional items and put them in a the req tuple
// and gather all the rest items in the opt tuple
type StripOptionnalsRec <T extends Tuple> =
undefined extends Last <T>
? T extends [...infer Init, any?]
? StripOptionnalsRec <Init>
: never
: T