Adrian Adkison
Adrian Adkison

Reputation: 3757

How to map an array of object property names to an array of the values that the names point to in a given object

const obj = { wheels: 4, lights: 2, doors: 4 }

someMapFunction(obj, { 
  props: ["wheel", "lights"], 
  format: (wheels, lights) => `${wheels}-${lights}` // "4-2"
})

How would I type someMapFunction so that typescript knows that props can only be keys of obj and that the format function will take all of the values that the props array values point to within obj?

Upvotes: 2

Views: 57

Answers (1)

Tobias S.
Tobias S.

Reputation: 23845

You would define the function like this:

function someMapFunction<
  T, 
  K extends (keyof T)[]
>(obj: T, propsAndFormat: { 
  props: [...K], 
  format: (...args: {
    [I in keyof K]: T[K[I]]
  }) => string 
}) {
  return null!
}

It has two generic parameters T and K. T describes the type of the object passed as obj while K is a tuple of keys of T. When we declare the parameter type of props, we use the variadic tuple syntax [...K] to infer K as a tuple and not and array since the order is important.

For format, we declare it to be a rest parameter where the order and type of elements are described by a tuple. To create this tuple, we can map over the elements I in the tuple K and use them to extract the corresponding type of T.


Playground

Upvotes: 2

Related Questions