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)