Home > other >  How write a typescript generics type for Array one-to-one conversion to Object
How write a typescript generics type for Array one-to-one conversion to Object

Time:11-03

Target

I want write a typescript generics type for Array one-to-one conversion to Object, the function like


transArrayToObject([
  [1, 'A'],
  [2, 'B'],
] as const)

// type output
{
  readonly A: 1;
  readonly B: 2;
}

I’ve tried

type Data = readonly (readonly [number, string])[]

type TransArrayToObject = <TD extends Data>(
  data: TD,
) => {
  readonly [K in TD[number][1]]: TD[number][0]
}

// Code details are omitted
const transArrayToObject = (() => ({})) as TransArrayToObject

transArrayToObject([
  [1, 'A'],
  [2, 'B'],
] as const)

but the type result is:

{
  readonly A: 1 | 2;
  readonly B: 1 | 2;
}

This is not what i want. I don't know how write 'A' corresponds to 1,'B' corresponds to 2,

CodePudding user response:

Consider this example:

const Tpl = [
  [1, 'A'],
  [2, 'B'],
] as const

type Tpl = typeof Tpl


type Transform<
  Tuple extends readonly any[],
  Result extends Readonly<Record<string, any>> = {}> =
  (Tuple extends []
    ? Result // last call
    : Tuple extends readonly [infer Head, ... infer Tail]
    ? (Head extends readonly [infer Value, infer Key]
      ? (Key extends PropertyKey
        ? Transform<Tail, Result & Readonly<Record<Key, Value>>>
        : never)
      : never)
    : never)

type Result = Transform<Tpl>

Playground

Transform - iterates through Tpl and infers each element. If element is a tuple with key/value pair, it creates a Record<Key,Value> , assigns it to Result and calls Transform recursively again

If you are interested in tuple manipulations, check my blog

  • Related