あるオブジェクト、型を限定したキー名を指定する型の書き方について
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>)
としたのも駄目でした。