MSW v2 で `HttpResponse.json()` の型がおかしいときの対処法
MSW v2 の `HttpResponse.json()` の第 2 引数の型は `Response` オブジェクトの初期化時に渡すオプションを指定できます。しかし、tsconfig.json の設定によっては、この型がおかしくなることがあります。その場合には、`tsconfig.json` の `compilerOptions.lib` に `dom` を追加するのが一時的な対処法です。
TL;DR
tsconfig.json
の compilerOptions.lib
に dom
を追加する。
{
"compilerOptions": {
"lib": ["dom"]
}
}
また、[node] Expose global ResponseInit; remove NodeJS.fetch namespace by thw0rted · Pull Request #67341 · DefinitelyTyped/DefinitelyTyped で問題が修正される予定です。
HttpResponse
クラス
MSW の MSW の v2 では、モックのレスポンスは Fetch API の Response オブジェクトを返すようになりました。Response
オブジェクトを返すクラスとして HttpResponse が用意されていますので、普段のモックの実装はこれを使うことになります。
import { http, HttpResponse } from "msw";
const handler = http.post("/user", (req, res: HttpResponse) => {
return HttpResponse.json(
{
name: "John",
age: 32,
},
{ status: 201 },
);
});
この HttpResponse.json
の第 2 引数には、Response
オブジェクトの初期化時に渡すオプションを指定できます。このオプションには status
、statusText
、headers
があります。
ResponseInit
型がおかしい問題
しかしながら、tsconfig.json
の設定によっては、HttpResponse.json
の第 2 引数の型がおかしくなることがあります。以下のように、{ type: any }
型としてサジェストされてしまっています。
なぜこのようなことが起きてしまっているのでしょうか?型定義を見てみましょう。HttpResponse.json
の第 2 引数の型は HttpResponseInit
となっています。
declare class HttpResponse extends Response {
/**
* Create a `Response` with a `Content-Type: "application/json"` body.
* @example
* HttpResponse.json({ firstName: 'John' })
* HttpResponse.json({ error: 'Not Authorized' }, { status: 401 })
*/
static json<BodyType extends JsonBodyType>(body?: BodyType | null, init?: HttpResponseInit): StrictResponse<BodyType>;
HttpResponseInit
は ResponseInit
を継承しています。
interface HttpResponseInit extends ResponseInit {
type?: ResponseType;
}
この ResponseInit
は lib.dom.d.ts
で定義されているため、もし tsconfig.json
が Node.js アプリケーション向けに設定されていて compilerOptions.lib
に dom
が含まれていない場合、ResponseInit
が見つからず正しい型情報が得られないということになります。
この問題を修正するには、tsconfig.json
の compilerOptions.lib
に dom
を追加する必要があります。
{
"compilerOptions": {
"lib": ["dom"]
}
}
この問題は Node.js に fetch API が提供されているのにも関わらず、@types/node
に ResponseInit
が定義されていないことに起因しています。この問題は [node] Expose global ResponseInit; remove NodeJS.fetch namespace by thw0rted · Pull Request #67341 · DefinitelyTyped/DefinitelyTyped がマージされることで解決される予定です。