エラーの内容
関数を呼び出すと、TypeScript が以下のエラーをスローします:
No overload matches this call. ts(2769)
その後に続くのは通常、大量のテキストです——各オーバーロードごとに1ブロック、引数がなぜ一致しなかったかが説明されます。読みにくいですが、流し読みの方法さえわかれば、その構造は実際に役立ちます。
要約すると:TypeScript がその関数で利用可能なすべてのシグネチャを順にチェックしたが、あなたの呼び出しはどれにも一致しなかった、ということです。
根本原因
関数のオーバーロードを使うと、渡される引数によって異なる動作をする関数を定義できます。TypeScript は引数を各オーバーロードシグネチャに順番に照合します。すべてに一致しなかった場合——ts(2769) が発生します。
最もよくある原因:
- すべてのオーバーロードが
stringを期待しているのに、ユニオン型(string | undefined)を渡している - 引数の数が違う——多すぎる、または少なすぎる
- 引数の型が一致しない(例:文字列が期待されているのにコールバックを渡すなど)
- 厳格なオーバーロードを持つサードパーティライブラリの型——React の
createElement、Node のfs.readFileなど - 自分で定義したオーバーロード関数で、実装シグネチャが宣言されたすべてのバリアントをカバーするには狭すぎる
修正1 — 呼び出し前に型を絞り込む
これが圧倒的に多い原因です。string | undefined の値があるのに、すべてのオーバーロードが string しか受け付けない場合、TypeScript は undefined を考慮したオーバーロードが存在しないため、どれを選べばよいかわかりません。
// ❌ エラー — name が undefined の可能性がある
function greet(name: string): string;
function greet(name: string, greeting: string): string;
function greet(name: string, greeting?: string) {
return greeting ? `${greeting}, ${name}` : `Hello, ${name}`;
}
const name: string | undefined = getName();
greet(name); // No overload matches this call. ts(2769)
// ✅ 修正 — 先に型を絞り込む
if (name !== undefined) {
greet(name);
}
// または Null 合体演算子で undefined を潰す
greet(name ?? 'stranger');
修正2 — 引数の数と順序を確認する
オーバーロードは位置に敏感です。引数が1つ多い、または間違ったスロットに入っているだけで、マッチングが失敗します。
// 定義されたオーバーロード:
function resize(width: number): void;
function resize(width: number, height: number): void;
// ❌ 間違い
resize('100px'); // ts(2769) — 数値ではなく文字列
resize(100, 200, 'cover'); // ts(2769) — 引数が3つ、最大は2つ
// ✅ 正しい
resize(100);
resize(100, 200);
修正3 — 実装シグネチャを広げる
自分でオーバーロードを書く場合、実際の関数本体である実装シグネチャは、宣言されたすべてのバリアントをカバーできる十分な広さが必要です。狭すぎると、本来有効なはずの呼び出しを TypeScript が拒否してしまいます。
// ❌ 壊れている — 実装シグネチャに string のブランチがない
function process(input: number): number;
function process(input: string): string;
function process(input: number): number | string { // ([]);
setItems([{ id: 1 }]); // 動作する
// ❌ 型なしの useRef — current が null 型になり、.focus() が使えない
const ref = useRef(null);
ref.current.focus(); // ts(2769)
// ✅ ref に正しい型を付ける
const ref = useRef(null);
if (ref.current) ref.current.focus();
修正5 — Node.js の fs とコールバックのオーバーロード
Node の組み込みモジュールは大量にオーバーロードされています。最もよく壊れるパターン:エンコーディング引数を忘れること。これにより TypeScript は string のオーバーロードではなく Buffer のオーバーロードを選択してしまいます。
import { readFile } from 'fs';
// ❌ エンコーディングなし — data が Buffer 型になり、.toString() で TypeScript が文句を言う
readFile('./config.json', (err, data) => {
console.log(data.toString());
});
// ✅ 'utf8' を追加 — TypeScript が string のオーバーロードを選び、data が string になる
readFile('./config.json', 'utf8', (err, data) => {
console.log(data);
});
修正6 — 最終手段としての型アサーション
厳格または不正確なサードパーティの型定義により、実行時には有効な呼び出しでも詰まることがあります。ピンポイントなアサーションを使えば、TypeScript を完全に無効にすることなく問題を回避できます。
// 関数自体をキャストする
import { someLibraryFn } from 'some-library';
(someLibraryFn as (arg: string | undefined) => void)(value);
// または引数だけをキャストする
someLibraryFn(value as string);
これはライブラリの型が本当に間違っている場合にのみ使用してください。まず実際の型の問題を修正しましょう——アサーションはバグを解決するのではなく隠すだけです。
エラー出力を読む
エラーを上から下へ読まないでください。リストされている最後のオーバーロードにスキップしましょう——通常それが意図したものに最も近く、そのエラーメッセージが最も対処しやすいです。
No overload matches this call.
Overload 1 of 2, '(input: number): number', gave the following error.
Argument of type 'string | number' is not assignable to parameter of type 'number'.
Overload 2 of 2, '(input: string): string', gave the following error.
Argument of type 'string | number' is not assignable to parameter of type 'string'.
明確な診断:引数が string | number なのに、各オーバーロードはどちらか一方しか期待していません。呼び出し前に型ガードで絞り込めば解決します。
修正を確認する
フルビルドはスキップして、変更した箇所だけを確認しましょう:
# 単一ファイルをチェック
npx tsc --noEmit path/to/your/file.ts
# またはプロジェクト全体
npx tsc --noEmit
# VS Code の場合 — 呼び出し箇所にカーソルを合わせる
# 赤い波線が消え、ホバーで正しい戻り値の型が表示される = 修正完了
予防策
- ユニオン型を呼び出し箇所に漏らさないようにしましょう。 関数が
string | undefinedを返し、呼び出し側が常に絞り込んで使うなら、欠損ケースで例外をスローすべきかどうか検討してください。 - 自分でオーバーロードを書くとき——呼び出し側には狭い宣言済みオーバーロードしか見えなくても、実装シグネチャは必要なだけ広く(
string | number | undefined)しておきましょう。 - 常に型引数を指定しましょう —
useState、useRef、Array.fromなどのジェネリック関数では、初期値から TypeScript が推論できない場合に特に重要です。 tsconfig.jsonで strict モードを有効にしましょう。 深夜2時のインテグレーション実行中ではなく、開発中にこれらの型の不一致を検出できます。

