1

I want to write a array to object function, which extracts one property as the index, like:

export const arrayToObject
    = <T, K extends keyof T, V extends T[K] & string>(arr: T[], key: K): { [v: V]: T } =>
    Object.assign({}, ...arr.map(item => ({[item[key]]: item})));

But it gives a compile error saying An index signature parameter type must be 'string' or 'number' for V, although I constraint the V type to be string. Why is the error and what is the proper way to do it?

2 Answers 2

2

V may extend T[K]. But since T is not constrained in any way when you index using item[key] all the compiler will know is that item[key] is of type T[K]. You need to constrain T so that for the key K the value will be of a type compatible with a property key.


export const arrayToObject
    = <T extends Record<K, V>, K extends keyof T, V extends PropertyKey>(arr: T[], key: K): { [v in T[K]]: T } =>
    Object.assign({}, ...arr.map(item => ({[item[key]]: item})));


let r = arrayToObject([{ key: "A", value: 0 }, { key: "B", value: 0 }], "key");
r.A.value //ok
r.B.value //ok
r.C.value //err

Play

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

Comments

0

I also found an working solution, which seems a little bit lighter:

export const arrayToObject =
   <T extends {[k in K]: number | string}, K extends keyof T>(arr: T[], key: K): { [k in T[K]]: T } =>
      Object.assign({}, ...arr.map(item => ({ [item[key]]: item })));

Comments

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.