diff --git a/docs/docs/04_client.md b/docs/docs/04_client.md index ec109d0..eee5b51 100644 --- a/docs/docs/04_client.md +++ b/docs/docs/04_client.md @@ -42,14 +42,15 @@ const data = await res.json(); // data is { userNames: string[] } If the response have multiple status codes, response type is union of each status code type. ```typescript +type Headers = { headers: { 'Content-Type': 'application/json' } }; type Spec = DefineApiEndpoints<{ "/users": { get: { responses: { - 200: { body: { names: string[] }; }; - 201: { body: { ok: boolean }; }; - 400: { body: { message: string; }; }; - 500: { body: { internalError: string; }; }; + 200: { body: { names: string[] }; } & Headers; + 201: { body: { ok: boolean }; } & Headers; + 400: { body: { message: string; }; } & Headers; + 500: { body: { internalError: string; }; } & Headers; }; }; } @@ -61,6 +62,12 @@ if (!res.ok) { // If res.ok is false, status code is 400 or 500 // So res.json() returns { message: string } | { internalError: string } const data = await res.json(); + + // Response headers are also type-checked. Content-Type is always 'application/json' + const contentType: 'application/json' = res.headers.get('Content-Type'); + // and, hasContentType is inferred as true, not boolean + const hasContentType: true = res.headers.has('Content-Type'); + return console.error(data); } // If res.ok is true, status code is 200 or 201 @@ -69,6 +76,20 @@ const data = await res.json(); // names is string[] console.log(data); ``` +:::info[Response headers limitation] + +Response headers are treated as an immutable object for strict type checking. +It means that you can not `append`, `set` or `delete` operation after the response object is created. +This is a limitation of the type system, not a runtime change. If you need mutable operations, you can cast types. + +```typescript +const immutableHeaders = res.headers +const mutableHeaders = res.headers as Headers; +``` + +::: + + ### Path & Path parameters zero-fetch accepts only the path that is defined in the API specification. diff --git a/src/fetch/index.t-test.ts b/src/fetch/index.t-test.ts index 457ee58..1f2fe9f 100644 --- a/src/fetch/index.t-test.ts +++ b/src/fetch/index.t-test.ts @@ -36,7 +36,12 @@ type ValidateUrlTestCase = [ type Spec = DefineApiEndpoints<{ "/users": { get: { - responses: { 200: { body: { prop: string } } }; + responses: { + 200: { + body: { prop: string }; + headers: { "Content-Type": "application/json" }; + }; + }; }; }; }>; @@ -49,6 +54,11 @@ type ValidateUrlTestCase = [ // methodを省略した場合はgetとして扱う const res = await f("/users", {}); (await res.json()).prop; + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const contentType: "application/json" = res.headers.get("Content-Type"); + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const hasContentType: true = res.headers.has("Content-Type"); } })(); }