2

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,

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

2 Comments

I get it, this example has benefited me a lot, thank you very much!
@SimonWong if you are interested in tuple manipulations, you can check my blog catchts.com/tuples

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.