Question: This implementation seems to be working fine ([Stackblitz](https://stackblitz.com/edit/typescript-distinct)):

```
    /**
     * Returns all the elements that are distinct by the 
     * `property` value.  Note that the implementation uses a `Map<string, E>` to
     * index the entities by key.  Therefore the more recent occurences 
     * matching a key instance will overwrite the previous ones.
     * 
     * @param property The name of the property to check for distinct values by.
     * @param entities The entities in the array.
     * 
     * @example
     * ```
     * let todos:Todo = [{ id: 1, "Lets do it!" }, {id: 2, "All done!"}];
     * let dtodos:Todo[] = distinct<Todo>(todos, 'id');
     */
    export function distinct<E>(entities:E[], property:string):E[] {
        let map:Map<string, E> = new Map();
        entities.forEach((e:E)=>{
            map.set(e[property], e);
        });
        return Array.from(map.values());
    }

```

The only thing is that VSCode draws a red squiggly under the `e[property]` part and the error message is:

> 
> Element implicitly has an 'any' type because type '{}' has no index signature.ts(7017)
> 
> 
> 

Is there a way to get rid of that?

Library Holding Implementation
------------------------------

I added the latest suggested implementation to this light weight state manager for objects and entities:

<https://www.npmjs.com/package/@fireflysemantics/slice>

```
npm i @fireflysemantics/slice
...
import {distinct} from '@fireflysemantics/slice/utilities';

```

Demo
----

<https://stackblitz.com/edit/typescript-slice-distinct>

Answer: 
The Error message is a bit misleading. His problem is, that it can not ensure that `e[property]` is of type `string` as you've defined the `Map`.

Make the key in the Map of type `any` as with so much flexibility you can not determine the type of the value either.

Additionally I'd type the `property` parameter as `keyof E` so TS ensures that I can only paste in valid property names for the type.

```
function distinct<E>(entities:E[], property:keyof E):E[] {
    let map:Map<any, E> = new Map();
    entities.forEach((e:E)=>{
        map.set(e[property], e);
    });
    return Array.from(map.values());
}

```
Based on [Thomas](https://stackoverflow.com/users/6567275/thomas)' answer, we can simplify both:

* JavaScript code: constructing the `Map` at once;
* TypeScript typing: adding the `K extends keyof E`, we can cast the tuples (`[E[K], E]`) used as `Map` constructor input parameter and remove the `any` type use.

Here the code:

```
function distinct<E, K extends keyof E>(entities: E[], property: K): E[] {
    const entitiesByProperty = new Map(entities.map(e => [e[property], e] as [E[K], E]));
    return Array.from(entitiesByProperty.values());
}

```

When calling `distinct()`, there's no need to specify the generic types since they can be inferred. Here's a working example:

```
enum Status { Pending = 0, Done = 1 }
interface Todo { id: number, label: string, status: Status, date?: Date }
const todos: Todo[] = [
    { id: 1, label: 'Task 1', status: Status.Pending },
    { id: 2, label: 'Task 2', status: Status.Pending },
    { id: 1, label: 'Task 1', status: Status.Done },
];
distinct(todos, 'id'); // [{ id: 1, ... status: 1 }, { id: 2, ... status: 0 }]

```