📌

ExpressのRequest型を拡張する

2024/02/10に公開1

Express の Request 型を拡張しようとしました、
別ファイルから読み込んでくるパターンの情報が見つからなかったため、
備忘録として残しておきます。

環境

$ node -v
v18.19.0
$ npm -v
10.2.3
package.json (一部抜粋)
{
  // ....
  "dependencies": {
    // ....
    "express": "^4.18.2",
    // ....
  },
  "devDependencies": {
    // ....
    "@types/express": "^4.17.21",
    "@types/node": "^18.18.2",
    // ....
    "typescript": "^5.3.3"
    // ....
  }
}

tsconfig

tsconfig.json (一部抜粋)
{
  "compilerOptions": {
    // ...
    "baseUrl": "./",
    "paths": {
      "~/*": ["./src/*"],
    },
    // ...
    "typeRoots": ["./src/@types"],
    // ...
  },
  // ...
}

型定義

src/@types/express/index.d.ts
// -----

type Context = {
  // Utility Typesは通常通り使える
  client: ReturnType<
    // 別ファイルから型を読み込む場合はimport()を利用する
    typeof import('openapi-fetch').default<
      // エイリアスも利用できる
      import('~/generated/api').paths
    >
  >;
}

declare namespace Express {
  interface Request {
    // 標準の型はそのまま利用できる
    token: string;
    // 同一ファイル内で定義された型は利用できる
    context: Context;
  }
}

// -----

型定義 (NG 例)

ファイル置き場間違い

vscode はエラーにならないが、ビルド時に失敗する

src/@types/express.d.ts
// -----

type Context = {
  // Utility Typesは通常通り使える
  client: ReturnType<
    // 別ファイルから型を読み込む場合はimport()を利用する
    typeof import('openapi-fetch').default<
      // エイリアスも利用できる
      import('~/generated/api').paths
    >
  >;
}

declare namespace Express {
  interface Request {
    // 標準の型はそのまま利用できる
    token: string;
    // 同一ファイル内で定義された型は利用できる
    context: Context;
  }
}

// -----

import from を利用する場合

vscode で型拡張が無視される

src/@types/express/index.d.ts
import type createClient from 'openapi-fetch';
import type { paths } from '~/generated/api';

// -----

type Context = {
  // Utility Typesは通常通り使える
  client: ReturnType<
    typeof createClient<paths>
  >;
}

declare namespace Express {
  interface Request {
    // 標準の型はそのまま利用できる
    token: string;
    // 同一ファイル内で定義された型は利用できる
    context: Context;
  }
}

// -----

最後に

他にももっとうまいやり方があれば、コメント欄で教えていただけると幸いです。
(chat GPT にも聞いてみましたが、動かないコードしか教えてくれませんでした。。。)

GitHubで編集を提案
株式会社ナンバーフォー

Discussion

からころ / karacoroからころ / karacoro

最近これにぶつかったんですが、同様の方法に落ちつきましたね。
Expressがそもそも、すでに数ヶ月単位で保守されておらず、似たようなバグが型定義にあるというissueもいくつか見受けられたので、根本解決はできませんでした…。