TypeScriptの型の指定で困っています。以下のような `toMap` という関数でコンパイルを通すことができません。

```

    const toMap = <T extends {}>(items: T[], key: keyof T) => {
        const map = {};
        items.forEach((item) => {
            map[item[key]] = item; // ここでエラー
        });
        return map;
    }
    
    const data = [
        { id: '1', value: { foo: 'bar' } },
        { id: '2', value: { hoge: 'piyo' } },
    ];
    
    toMap(data, 'id'); // => { '1': { ... }, '2': { ... } }
    
```

`<T extends {}>(items: T[], key: any): { [key: string]: T }`
とでも妥協すればいいのはわかるのですが、 `any` を使わずに解決したいと思っています。

<https://www.typescriptlang.org/docs/handbook/release-
notes/typescript-2-8.html#example-2> の `FunctionPropertyNames<T>` を参考に `type
StringPropertyNames<T> = { [K in keyof T]: T[K] extends string ? K : never
}[keyof T];` を定義し、 `<T extends {}>(items: T[], key: StringPropertyNames<T>)`
としたのも駄目でした。
CC BY-SA 4.0
2019-06-24T09:52:00.580
56064
2019-08-23T10:12:42.903
29556
question
typescript
あるオブジェクト、型を限定したキー名を指定する型の書き方について
keyで指定されたプロパティがstringである型の配列を受け取る関数という形では書けました。

```

    function toMap<K extends string, T extends {[I in K]: string}>(items: T[], key: K) {
        const map: { [index: string]: T } = {};
    
        items.forEach((item: E) => {
            const id = item[key];
            map[id] = item;
        });
        return map;
    }
    
```
CC BY-SA 4.0
2019-08-23T10:12:42.903
57569
2019-08-23T10:12:42.903
241
56064
answer