Code Fix

中級

インデックスシグネチャと矛盾する型のプロパティを宣言するとエラーになる

[key: string]: numberのようなインデックスシグネチャを持つinterfaceでは、個別に宣言する具体的なプロパティも、インデックスシグネチャの型と互換性がなければ宣言できません。

エラーメッセージの読み方

main.ts(3,3): error TS2411: Property 'name' of type 'string' is not assignable to 'string' index type 'number'.
main.ts
ファイル名
3
行番号
3
列番号 — この位置でtscが検査に失敗しました
TS2411
エラーコード — 検索するとTypeScriptの解説が見つかります
Property 'name' of type 'string' is not assignable to 'string' index type 'number'.
内容 — 期待していたもの、または受け付けられなかったもの

このエラーが出る典型パターン

パターン1

 1  interface Dict {
 2    [key: string]: number;
 3    name: string ;
            ^
 4  }
 5  console.log("ok");
main.ts(3,3): error TS2411: Property 'name' of type 'string' is not assignable to 'string' index type 'number'.

インデックスシグネチャは全プロパティがnumber型であることを要求します。nameをstring型で宣言すると矛盾します。

直し方: name: string を count: number にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  interface Scores {
 2    [key: string]: number;
 3    label: boolean;
             ^
 4  }
 5  console.log("ok");
main.ts(3,3): error TS2411: Property 'label' of type 'boolean' is not assignable to 'string' index type 'number'.

labelをboolean型で宣言すると、number型を要求するインデックスシグネチャと矛盾します。

直し方: label: boolean を total: number にします。

この問題を解いてみる →

パターン3

 1  interface Flags {
 2    [key: string]: boolean;
 3    count: number  ;
             ^
 4  }
 5  console.log("ok");
main.ts(3,3): error TS2411: Property 'count' of type 'number' is not assignable to 'string' index type 'boolean'.

このインデックスシグネチャはboolean型を要求します。countをnumber型で宣言すると矛盾します。

直し方: count: number を active: boolean にします。

この問題を解いてみる →

パターン4

 1  interface Prices {
 2    [key: string]: number;
 3    label: string;
            ^
 4  }
 5  console.log("ok");
main.ts(3,3): error TS2411: Property 'label' of type 'string' is not assignable to 'string' index type 'number'.

インデックスシグネチャは全プロパティがnumber型であることを要求します。labelをstring型で宣言すると矛盾します。

直し方: label: string を base: number にします。

この問題を解いてみる →

パターン5

 1  interface Toggles {
 2    [key: string]: boolean;
 3    level: number   ;
              ^
 4  }
 5  console.log("ok");
main.ts(3,3): error TS2411: Property 'level' of type 'number' is not assignable to 'string' index type 'boolean'.

このインデックスシグネチャはboolean型を要求します。levelをnumber型で宣言すると矛盾します。

直し方: level: number を enabled: boolean にします。

この問題を解いてみる →

よくある誤解

「個別に書いたプロパティは、インデックスシグネチャより優先されるはず」という考えは誤りです。TypeScriptは両方が矛盾なく共存できることを要求し、型が食い違う時点でinterfaceの宣言自体をエラーにします。

実務での勘所

この制約は恣意的なルールではなく、型システムの一貫性を保つための論理的な必然です。[key: string]: numberと宣言すると、「文字列であるすべてのキーの値はnumber型である」という約束になります。個別に宣言したプロパティ名も文字列である以上、この約束の対象から逃れられません。もし個別のプロパティにだけ違う型を許してしまうと、obj.knownPropという書き方とobj["knownProp"]という動的な書き方で、同じ値のはずなのに型が食い違うという矛盾が生まれてしまいます。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)