📌
ExpressのRequest型を拡張する
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 にも聞いてみましたが、動かないコードしか教えてくれませんでした。。。)
Discussion
最近これにぶつかったんですが、同様の方法に落ちつきましたね。
Expressがそもそも、すでに数ヶ月単位で保守されておらず、似たようなバグが型定義にあるというissueもいくつか見受けられたので、根本解決はできませんでした…。