結論
-
Index signature for type 'string' is missing in type 'XXXX'
が出たということは、エラーメッセージの文面通り、実際その型にはインデックスシグネチャが定義されていないはずだよ - だから、ないなら定義してやればいい
もっと詳しく
このエラーメッセージが出たということは、このページに来た人は多分次のようなコードを書いていると思う。インデックスシグネチャ [key: string]: string;
を定義した型を、何らかのFunctionの引数にしているはずだ。きっとその引数に、何らかのinterfaceを指定しているよね。
interface DictionaryType {
[key: string]: string;
};
function logDictionary(dictionary: DictionaryType) {
console.log(dictionary);
}
interface User {
name: string;
};
const user001: User = {
name: "user001",
};
// ---- エラー発生! ----
// Argument of type 'User' is not assignable to parameter of type 'DictionaryType'.
// Index signature for type 'string' is missing in type 'User'.ts(2345)
logDictionary(user001);
このコードだと、logDictionaryの引数 user001
のところにエラーが出ると思う。エラーの内容は文面そのまま、「この引数にはインデックスシグネチャがないよ!」という意味。
一見するとインデックスシグネチャ [key: string]: string;
に name: string;
は違反していないのだから、問題ないはずだって思うかもしれないけど、怒られているポイントはそこじゃない。
あくまで「インデックスシグネチャがないよ!」って言われているのだから、素直にその言葉に従おう。
で、そのインデックスシグネチャの追加方法は2つある。
インデックスシグネチャの追加方法1. 普通に自分で書く
一つは当然ながら、言われた通りインデックスシグネチャを明示的に追加してやることだ。特別なことは何もない。ただただエラーが出た型 interface User
を次のように書き換えてやればいい。
interface User {
name: string;
[key: string]: string;
}
これでエラーは消える。
でも、これじゃちょっと冗長な感じするよね。それなら次のやり方で書けばいい。
インデックスシグネチャの追加方法2. interfaceではなく型エイリアス(type)を使う
type User = {
name: string;
}
これだけでいい。
「え、これのどこがインデックスシグネチャを追加してるの??」 って思うかもしれないけど、実は型エイリアス(type)には、「暗黙的なインデックスシグネチャ」が備わっている。だからこれだけでインデックスシグネチャが付与されて、冒頭のエラーが解消されるんだ。
そのほかのアプローチ
型の修正ではなく、値の取り扱いを変えるだけでもこのエラーを解消できる。
具体的にはスプレット構文で一度別のオブジェクトに展開してやることで、元々の interface User
としての制約から解き放たれていて、そのためにエラーが解消されるわけだね。
interface DictionaryType {
[key: string]: string;
};
function logDictionary(dictionary: DictionaryType) {
console.log(dictionary);
}
interface User {
name: string;
};
const user001: User = {
name: "user001",
};
logDictionary({ ...user001 });
まとめ
Index signature for type 'string' is missing in type 'XXXX'
が出たなら、次のいずれかでエラーを解消できる。
- エラーになった値のinterfaceに明示的にインデックスシグネチャを追加する
- エラーになった値のinterfaceを型エイリアス(type)に変える
- エラーになった値をスプレッド構文で展開して新たなオブジェクトにしてやる
おまけ
この件に関しては microsoft/TypeScript のIssue上で過去に議論が白熱したみたい。もっと詳しく知りたい人は、読んでみてね!