TypeScript で Object.keys(obj)
でキーの配列を作ってループさせてループ内でキーでオブジェクトのデータにアクセスしようとして型エラーになってしまったのメモ
e.g.
例としてデータ構造が良くないけど、ID をキーにしたオブジェクトみたいなイメージで
const idols = { hosimiya: {name: '星宮いちご', type: 'cute', brand: 'Angely Sugar'}, kirija: {name: '霧矢あおい', type: 'cool', brand: 'FUTURING GIRL'}, shibuki: {name: '紫吹蘭', type: 'sexy', brand: 'SPICY AGEHA'}, }; Object.keys(idols).map((key) => { const data = idols[key]; // => Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ hosimiya: … // => No index signature with a parameter of type 'string' was found on type '{ hosimiya: … console.log(data); });
- Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ hosimiya: …
- No index signature with a parameter of type 'string' was found on type '{ hosimiya: …
オブジェクトに [key]
でアクセスすると暗黙的に型変換された key
が idols
オブジェクトのインデックスと一致しないということっぽい。
(ᐡ •̥ ̫ •̥ ᐡ) なんもわからん…
Object.keys
で作られる配列がオブジェクトのキーの配列だと証明できればOK
keyof
を使うとプロパティ名を |
でつないだ型 ( プロパティ名の直和型 ) が作れる
interface Soleil { 'hosimiya': { name: string, type: string, brand: 'string' }; 'kirija': { name: string, type: string, brand: 'string' }; 'shibuki': { name: string, type: string, brand: 'string' }; } type SoleilKey = keyof Soleil; // => type SoleilKey = 'hosimiya' | 'kirija' | 'shibuki';
Object.keys(idols)
が SoleilKey[]
になっていれば、map
に渡される引数は SoleilKey
である。ということになるっぽい。
修正するとこんな感じ。
interface idolData { name: string; type: string; brand: string; } interface Soleil { hosimiya: idolData; kirija: idolData; shibuki: idolData; } const idols: Soleil = { hosimiya: {name: '星宮いちご', type: 'cute', brand: 'Angely Sugar'}, kirija: {name: '霧矢あおい', type: 'cool', brand: 'FUTURING GIRL'}, shibuki: {name: '紫吹蘭', type: 'sexy', brand: 'SPICY AGEHA'}, }; (Object.keys(idols) as (keyof Soleil)[]).map((key) => { const data = idols[key]; // 👌👌👌 console.log(data); });
₍ ᐢ. ̫ .ᐢ ₎👌 できた
おまけ
今回のレベルだと [key: string]
で型定義してしまえば、map の所でゴニョゴニョしなくても大丈夫っぽい
interface idolData { name: string; type: string; brand: string; } interface Idols { [key: string]: idolData; } const idols: Idols = { kurebayashi: {name: '紅林珠璃', type: 'sexy', brand: 'Sangria Rosa'}, Amahane: {name: '天羽まどか', type: 'cute', brand: 'Angely Sugar'}, Kurosawa: {name: '黒沢凛', type: 'cool', brand: 'Dance Fusion'}, }; Object.keys(idols).map((key) => { const data = idols[key]; // 👌👌👌 console.log(data); });
TypeScript チョットづつ慣れてきてるけどまだ何もわからん…
[参考]
- Object.keysの型がstring[]になってしまう問題の対策 - Qiita
- Typescript ブラケット記法(Object[key])でno index signatureエラーをtype safeに解決したい。 - aknow2
- TypeScript 2.1のkeyofとかMapped typesがアツい - Qiita

アイカツ! キラキラ★シールブック アニメ (まるごとシールブックDX)
- 発売日: 2014/03/27
- メディア: 文庫