No overload matches this call の原因と直し方
複数のシグネチャ(オーバーロード)を持つ関数を、どの組み合わせにも当てはまらない引数の型で呼び出したときに出るエラーです。エラーメッセージには、試したすべてのオーバーロードでの失敗理由が列挙されます。
エラーメッセージの読み方
main.ts(6,13): error TS2769: No overload matches this call.
main.ts- ファイル名
6- 行番号
13- 列番号 — この位置でtscが検査に失敗しました
TS2769- エラーコード — 検索するとTypeScriptの解説が見つかります
No overload matches this call.- 内容 — 期待していたもの、または受け付けられなかったもの
このエラーが出る典型パターン
パターン1
1 function combine(a: string, b: string): string; 2 function combine(a: number, b: number): number; 3 function combine(a: any, b: any): any { 4 return a + b; 5 } 6 console.log(combine("x", 5 )); ^
combineはstring同士かnumber同士の組み合わせしか受け付けません。string と number を混ぜた呼び出しはどちらのシグネチャにも一致しません。
直し方: "x", 5 を "x", "y" にします。
パターン2
1 function merge(a: string[], b: string[]): string[]; 2 function merge(a: number[], b: number[]): number[]; 3 function merge(a: any, b: any): any { 4 return a.concat(b); 5 } 6 console.log(merge([1, 2], ["a"])); ^
mergeは同じ要素型の配列同士しか受け付けません。number[]とstring[]を混ぜるとどちらのシグネチャにも一致しません。
直し方: [1, 2], ["a"] を [1, 2], [3] にします。
パターン3
1 function wrapValue(a: string): string[]; 2 function wrapValue(a: number): number[]; 3 function wrapValue(a: any): any { 4 return [a]; 5 } 6 console.log(wrapValue(true)); ^
wrapValueはstringかnumberしか受け付けません。boolean型のtrueはどちらのシグネチャにも一致しません。
直し方: true を 1 にします。
パターン4
1 function joinVals(a: string, b: string): string; 2 function joinVals(a: number, b: number): number; 3 function joinVals(a: any, b: any): any { 4 return a + b; 5 } 6 console.log(joinVals(1, "x")); ^
joinValsはstring同士かnumber同士の組み合わせしか受け付けません。
直し方: 1, "x" を 1, 2 にします。
パターン5
1 function pickFirst(a: string[]): string; 2 function pickFirst(a: number[]): number; 3 function pickFirst(a: any): any { 4 return a[0]; 5 } 6 console.log(pickFirst(true )); ^
pickFirstはstring[]かnumber[]しか受け付けません。boolean型のtrueはどちらのシグネチャにも一致しません。
直し方: true を [1, 2] にします。
よくある誤解
「実装本体(最後のシグネチャ)の型さえ満たせば呼び出せるはず」という考えは誤りです。実装シグネチャは外部からの呼び出しには使われず、公開されているオーバーロードのどれかに一致する必要があります。
実務での勘所
実装シグネチャ(最後に書く、本体を持つシグネチャ)が呼び出し側から見えないのには理由があります。実装シグネチャは、公開されている複数のオーバーロードすべてに対応できるよう、意図的に緩く(unionやanyを使って)書かれていることがほとんどです。もしこの緩いシグネチャがそのまま外部から見えてしまうと、呼び出し側は本来のオーバーロードごとの厳密な型チェックの恩恵を受けられなくなります。呼び出し側には精密な複数のオーバーロードだけを見せ、内部の実装は自由な型で書けるようにする、という役割分担です。