Skip to content

Express.jsで発生する「No overload matches this call」TypeScriptエラーの解決策

問題の発生原因

Express.jsアプリケーションでルートハンドラーを定義する際、以下のTypeScriptエラーが発生します:

text
No overload matches this call.
Argument of type '(req: Request, res: Response) ⇒ Promise<...>' 
is not assignable to parameter of type 'Application<Record<string, any>>'.

このエラーの主な原因は

  1. ルートハンドラーがresオブジェクトを返却しようとしている
  2. TypeScriptの型システムとExpressの関数シグネチャの不一致
  3. 非同期ハンドラー(async)における戻り値型の扱いの違い

Expressの型定義では、ルートハンドラーは**値を返さない(void)**ことが期待されています。しかしasync関数は常にPromiseを返すため、型システムが矛盾を検出しています。


解決方法

以下のいずれかの方法で問題を解決できます:

✅ 方法1: レスポンス後に明示的にreturnする(推奨)

レスポンス送信後にreturn;で関数を終了します:

ts
router.post('/create-checkout-session', async (req: Request, res: Response) => {
  if (!validUser(req)) {
    res.status(400).send({ message: 'Invalid user' });
    return; // 戻り値なしで終了
  }
  
  // 正常処理続行
});

✅ 方法2: void演算子を使用する

レスポンスの発行部分をvoidで明示的に未評価にします:

ts
router.post('/create-checkout-session', async (req: Request, res: Response) => {
  if (errorCondition) {
    void res.status(401).json({ error: 'Unauthorized' });
    return;
  }
  
  // 正常処理
});

⚠️ 方法3: 型定義のダウングレード(一時的対策)

根本的な解決ではありませんが、一時的な回避策として@types/expressをv4にダウングレード:

bash
npm install -D @types/express@4

なぜこれが解決策なのか

  1. 戻り値の矛盾解消
    Expressはルートハンドラーで戻り値を受け取りません → 明示的なreturnvoidを返す

  2. 型システムとランタイムの整合
    async関数のPromise戻り値とExpressのvoid期待を整合させる

  3. リクエスト処理フローの明確化
    レスポンス後に処理を継続しないことをコードで明示


補足アドバイス

  1. エラーハンドリングのベストプラクティス
    一貫したエラーレスポンス構造を使用:

    ts
    if (error) {
      res.status(400).json({
        error: 'Bad Request',
        details: error.message
      });
      return;
    }
  2. ミドルウェアでの統一処理
    認証チェックなどは専用ミドルウェアに分離:

    ts
    // 認証ミドルウェア
    const authMiddleware = (req: Request, res: Response, next: NextFunction) => {
      if (!req.user) return res.status(401).send('Unauthorized');
      next();
    };
    
    // ルート適用
    router.post('/create-checkout-session', authMiddleware, async (req, res) => { ... });
  3. 型定義バージョンの確認
    パッケージの整合性を確認:

    json
    "devDependencies": {
      "@types/express": "^4.17.21",
      "express": "^4.18.3"
    }

まとめ

No overload matches this callエラーは、Expressのルートハンドラーで誤ってresオブジェクトを返そうとする際に発生します。res操作後に戻り値のないreturnを明示することで、TypeScriptの型システムとExpressの期待動作を一致させられます。型定義のダウングレードは一時的な回避策として有効ですが、根本的な解決ではありません。