[SOLVED] tuple mapper function typing

Issue

I need to type a function that takes a tuple in and outputs a mapped version of it
as a first try I defined an identity tuple that returns a tuple of same type

    declare const tupleIdentity: <Tup extends readonly any[]>(tup: Tup) => Tup
    const [a, b, c, d] = tupleIdentity([1, 's', 3]) // a:number, b:string, c:number, d:undefined

that’s great, it tracks tuple’s length and elements types !
but couldn’t find a typing returning a mapped version of the tuple
e.g. an object wrapping each element

    // a naive attempt :

    type Wrap<T> = { wrapped: T }
    declare const tupleMapper: <Tup extends readonly any[]>(tup: Tup) 
      => Tup extends Array<infer T> ? Wrap<T>[] : never
    const [x, y, z] = tupleMapper([1, 's', 3]) // x,y,z: Wrap<string | number> | undefined

can Ts type system declare such a typing ?

Solution

You can declare the type using a mapped type (which yields a tuple when applied to a tuple type):

type Wrap<T> = { wrapped: T }

declare const tupleMapper: <Tup extends readonly any[]>(tup: Tup) => 
  {[K in keyof Tup]: Wrap<Tup[K]>}

const [x, y, z] = tupleMapper([1, 's', 3]) // [Wrap<number>, Wrap<string>, Wrap<number>]
// x: Wrap<number>
// y: Wrap<string>
// z: Wrap<number>

Answered By – Oblosys

Answer Checked By – Candace Johnson (BugsFixing Volunteer)

Leave a Reply

Your email address will not be published. Required fields are marked *