Skip to content

Commit ff8fa88

Browse files
authored
Merge pull request #5 from tknf/fix/request-first-arg-type-interfaces
fix(types): Improve TypeScript Type Inference
2 parents ed40451 + 4e77574 commit ff8fa88

File tree

6 files changed

+32
-31
lines changed

6 files changed

+32
-31
lines changed

examples/basic-usage.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -144,12 +144,12 @@ function typeSafeExample() {
144144
const response = await api.request("POST /users", {
145145
body: userData, // Type-checked against CreateUserSchema
146146
});
147-
147+
148148
// Access both data and metadata
149149
console.log("Created user:", response.data);
150150
console.log("Location header:", response.headers.get("location"));
151151
console.log("Status:", response.status);
152-
152+
153153
return response.data;
154154
},
155155

@@ -214,7 +214,7 @@ async function errorHandlingExample() {
214214
const response = await api.request("GET /users/{id}", {
215215
params: { id: "123" },
216216
});
217-
217+
218218
console.log("User data:", response.data);
219219
console.log("Status:", response.status);
220220
console.log("Headers:", response.headers);
@@ -250,16 +250,16 @@ async function rawResponseExample() {
250250

251251
// Access raw Response for advanced operations
252252
const rawResponse = response["~raw"];
253-
253+
254254
// Stream the response body
255255
const reader = rawResponse.body?.getReader();
256-
256+
257257
// Check response headers
258258
const contentType = rawResponse.headers.get("content-type");
259259
const contentLength = rawResponse.headers.get("content-length");
260-
260+
261261
console.log(`Downloading ${contentType}, size: ${contentLength} bytes`);
262-
262+
263263
// Process stream...
264264
if (reader) {
265265
// Handle streaming...
@@ -273,10 +273,10 @@ async function rawResponseExample() {
273273
}
274274

275275
// Export usage examples
276-
export {
277-
basicExample,
278-
typeSafeExample,
276+
export {
277+
basicExample,
278+
typeSafeExample,
279279
advancedExample,
280280
errorHandlingExample,
281-
rawResponseExample
281+
rawResponseExample
282282
};

examples/nodejs-usage.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ function nodeJsModernExample() {
3030
const response = await api.request("GET /users/{id}", {
3131
params: { id },
3232
});
33-
33+
3434
console.log("User data:", response.data);
3535
console.log("Response status:", response.status);
3636
console.log("Content-Type:", response.headers.get("content-type"));
37-
37+
3838
return response.data;
3939
},
4040
};
@@ -46,7 +46,7 @@ function nodeJsModernExample() {
4646
async function nodeJsCustomFetchExample() {
4747
// For Node.js < 18 or custom fetch implementation
4848
const { default: nodeFetch } = await import("node-fetch");
49-
49+
5050
const client = new TypeFetcher({
5151
baseURL: "https://jsonplaceholder.typicode.com",
5252
fetch: nodeFetch as unknown as typeof globalThis.fetch,
@@ -66,7 +66,7 @@ async function nodeJsCustomFetchExample() {
6666
const response = await api.request("GET /users/{id}", {
6767
params: { id },
6868
});
69-
69+
7070
return {
7171
user: response.data,
7272
status: response.status,
@@ -82,7 +82,7 @@ async function nodeJsCustomFetchExample() {
8282
async function nodeJsUndiciExample() {
8383
// Using undici as fetch implementation
8484
const { fetch } = await import("undici");
85-
85+
8686
const client = new TypeFetcher({
8787
baseURL: "https://jsonplaceholder.typicode.com",
8888
fetch: fetch as unknown as typeof globalThis.fetch,
@@ -93,13 +93,13 @@ async function nodeJsUndiciExample() {
9393
return {
9494
async getUsers() {
9595
const response = await api.request("GET /users");
96-
97-
console.log("Fetched", response.data?.length || 0, "users");
96+
97+
console.log("Fetched", (response.data as any)?.length || 0, "users");
9898
console.log("Response headers:");
9999
for (const [key, value] of response.headers.entries()) {
100100
console.log(` ${key}: ${value}`);
101101
}
102-
102+
103103
return response.data;
104104
},
105105
};

examples/signal-and-raw-usage.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ async function combinedExample() {
145145
// Check rate limiting headers directly from response
146146
const rateLimitRemaining = response.headers.get("x-ratelimit-remaining");
147147
const rateLimitReset = response.headers.get("x-ratelimit-reset");
148-
148+
149149
console.log("Rate limit remaining:", rateLimitRemaining);
150150
if (rateLimitReset) {
151151
const resetDate = new Date(parseInt(rateLimitReset) * 1000);
@@ -200,7 +200,7 @@ async function longPollingExample() {
200200

201201
try {
202202
console.log("Starting long polling for events...");
203-
203+
204204
const response = await api.request("GET /events", {
205205
query: {
206206
timeout: "30", // Server-side timeout
@@ -220,7 +220,7 @@ async function longPollingExample() {
220220
console.log("Connection:", connection);
221221
} catch (error) {
222222
clearTimeout(cancelTimeout);
223-
223+
224224
if (error instanceof Error && error.name === "AbortError") {
225225
console.log("Long polling was cancelled");
226226
} else {
@@ -265,7 +265,7 @@ async function typeInferenceExample() {
265265

266266
// Raw response access also available:
267267
console.log("Raw response status:", response["~raw"].status); // number
268-
268+
269269
// Clean separation of data and metadata
270270
const { data, status, headers, url, "~raw": rawResponse } = response;
271271
console.log("Post data:", data); // { id: number, title: string, body: string, userId: number }

examples/valibot-usage.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,10 @@ function valibotDirectExample() {
7474
const response = await api.request("POST /users", {
7575
body: userData,
7676
});
77-
77+
7878
console.log("Created user with status:", response.status);
7979
console.log("Location header:", response.headers.get("location"));
80-
80+
8181
return response.data;
8282
},
8383

@@ -86,7 +86,7 @@ function valibotDirectExample() {
8686
params: { id },
8787
body: userData,
8888
});
89-
89+
9090
return {
9191
user: response.data,
9292
status: response.status,

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@tknf/typefetcher",
3-
"version": "1.0.0",
3+
"version": "1.0.1",
44
"description": "TypeScript-first API client with Standard Schema support, providing excellent DX and strict type safety.",
55
"keywords": [
66
"typescript",

src/client.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ type ResponseForEndpoint<
8888
* TypeScript-first API client with Standard Schema support
8989
* Provides type-safe HTTP requests with runtime validation
9090
*/
91-
export class TypeFetcher<T extends EndpointMap = Record<string, never>> {
91+
export class TypeFetcher<T extends EndpointMap = Record<never, never>> {
9292
private endpoints: T;
9393
private config: TypeFetcherConfig;
9494
private fetch: typeof globalThis.fetch;
@@ -112,28 +112,29 @@ export class TypeFetcher<T extends EndpointMap = Record<string, never>> {
112112
path: Path,
113113
schema?: Schema
114114
): TypeFetcher<T & Record<`${Method} ${Path}`, EndpointDefinition<Method, Path, Schema>>> {
115-
const key = `${method} ${path}` as const;
115+
const key = `${method} ${path}` as `${Method} ${Path}`;
116116
const newEndpoints = {
117117
...this.endpoints,
118118
[key]: {
119119
method,
120120
path,
121121
schema,
122-
},
122+
} as EndpointDefinition<Method, Path, Schema>,
123123
} as T & Record<`${Method} ${Path}`, EndpointDefinition<Method, Path, Schema>>;
124124

125125
const newFetcher = new TypeFetcher<
126126
T & Record<`${Method} ${Path}`, EndpointDefinition<Method, Path, Schema>>
127127
>(this.config);
128128
newFetcher.endpoints = newEndpoints;
129+
newFetcher.fetch = this.fetch;
129130
return newFetcher;
130131
}
131132

132133
/**
133134
* Execute a request to a registered endpoint
134135
* Validates request parameters and response data if schemas are provided
135136
*/
136-
async request<K extends string & keyof T>(
137+
async request<K extends keyof T>(
137138
key: K,
138139
options?: RequestOptionsForEndpoint<T, K>
139140
): Promise<ResponseForEndpoint<T, K>> {

0 commit comments

Comments
 (0)