0

I'm trying to convert an array of object to a map, indexed by an attribue value of the Object in typescript 4.1.5

Furthermore I want only the attributes of a certain type (here string)

A very similar question have been asked in javascript here : Convert object array to hash map, indexed by an attribute value of the Object

type Foo = {
        a : string
        b : number
}

const foos: Foo[] = []
// should only propose to index by 'a'
const foos_indexed_by_a = indexArrayByKey(foos, 'a')

function indexArrayByKey<T> (array: T[], key: Extract<keyof T, string>): Map<string, T> {
        return array.reduce((map, obj) => map.set(obj[key], obj), new Map<string, T>())
}

Playground Link

For now I can't access property key of obj (compilation failure)

Thanks for your help :)

1 Answer 1

2

To filter the keys based on which have a string value you can't use Extarct that filters the keys which are strings (not number or symbol). You can use KeyOfType described here

type KeyOfType<T, V> = keyof {
    [P in keyof T as T[P] extends V? P: never]: any
}
function indexArrayByKey<T, K extends KeyOfType<T, string>> (array: T[], key: K): Map<T[K], T> {
        return array.reduce((map, obj) => map.set(obj[key], obj), new Map<T[K], T>())
}

Playground Link

We use T[K] instead of string because T[K] could also be a subtype of string so TS would complain at string, but for cases this will work well.

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

5 Comments

I think you were right my answer was missing the point. The question clearly says "indexed by an attribue value of the Object". sigh :-)
Thanks your answer works really well in typescript v4.5.4 but not in the one I'm using v4.1.5. I should have specified it sorry. Do you have a solution for it ?
@Nainpo you can just swap out the definition of KeyOfType with the older one here stackoverflow.com/questions/51419176/… The rest should work.
Playground link for older compatible version: typescriptlang.org/play?ts=4.1.5#code/…
Thanks for the new definition it's ok ! :)

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.