1

I want to convert an array of {key:'A',value:'B'} to an indexed object {A:{key:'A',value:'B'}}. How can I define the return type to reflect the result object ?

function toObject<T = any>(a: Iterable<T & { key }>): { [k in /* !!not like this!! */ keyof T]: T } {
  return [...a].reduce((a, v) => (a[v.key] = v, a), {}) as any;
}

// Hope there is a hint for A and B
toObject([{key:'A',value:'B'},{key:'B'}]).A

EDIT

Thanks to @Niilo Keinänen, the answer is very close, I changed to param to array, also works.

const toObject = <K extends string, T = any>(arr: Array<T & { value: K }>): { [k in K]: T }  {
  const obj: any = { };
  arr.forEach(v => obj[v.value] = v);
  return obj;
}
2
  • Do all the key-value-pairs have the same type of "value" (string in example case) ? Commented Jun 26, 2019 at 6:14
  • @NiiloKeinänen the value field is not matter, toObject([{ key: 'first', value: 'second' }])= { first: { key: 'first', value: 'second' }} Commented Jun 26, 2019 at 6:42

1 Answer 1

1

Did I understand correctly:

toObject({ key: 'first', value: 'second' })
= { first: 'second' } ?

This would seem to work:

const toObject = <K extends string, V, T extends { [P in K]: V }>(keyValuePair: { key: K, value: V }): T => {
    const obj: any = {}
    obj[keyValuePair.key] = keyValuePair.value
    return obj as T
}

Maybe you could also avoid the dirty any type somehow, not sure.

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

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.