Request Extractors
As your requests become more complex with response types, payloads, parameters, and errors, their inferred types can become large and unwieldy. Hyper-fetch provides a set of utility type extractors that allow you to easily grab a specific piece of a request's type. This is incredibly useful for creating reusable types, passing types to other functions, or simply for better readability.
What you'll learn
- Why type extractors are useful for complex requests.
- How to use various extractors like
ExtractResponseType
,ExtractPayloadType
, andExtractErrorType
. - How to build a complete, reusable example using multiple extractors.
- A quick reference for all available type extractors.
Why is it helpful?
- Type Reusability: Extract and reuse parts of a request's type, like
response
orpayload
, without duplicating definitions. - Decoupling: Decouple components from the full request definition. A component might only need to know about the
ResponseType
, not the entire request object. - Clarity: Simplifies complex type signatures, making function parameters and variable types easier to read and understand.
- Interoperability: Makes it easier to pass request-related types to other libraries or utility functions.
Practical Example
Instead of a simple list, let's look at a real-world scenario where we define a complex request and then use extractors to deconstruct its type for use in other parts of our application.
import {
createClient,
ExtractResponseType,
ExtractPayloadType,
ExtractErrorType,
ExtractParamsType,
} from "@hyper-fetch/core";
export const client = createClient()({
url: "https://api.example.com",
}).setExtra<{ error: { message: string } | Error }>();
// 1. Define a complex request
const updateUser = client.createRequest<{
response: { id: number; name: string; email: string; updatedAt: string };
payload: { name?: string; email?: string };
localError: { errors: { email?: string } };
}>()({
method: "PATCH",
endpoint: "/users/:userId",
});
// 2. Now, let's extract types from it
type UserResponse = ExtractResponseType<typeof updateUser>;
type UserPayload = ExtractPayloadType<typeof updateUser>;
type UserError = ExtractErrorType<typeof updateUser>;
type UserParams = ExtractParamsType<typeof updateUser>;
// 3. We can now use these types elsewhere in our application
function displayUser(user: UserResponse) {
console.log(`User: ${user.name} (${user.email})`);
}
async function handleUpdate(params: UserParams, payload: UserPayload) {
const { data, error } = await updateUser.setParams(params).send({ data: payload });
if (data) {
displayUser(data);
} else {
logError(error);
}
}
function logError(error: UserError) {
// `error` is a union of the global and local error types
if (error instanceof Error) {
console.error(error.message);
} else if ("errors" in error) {
console.error("Validation Error:", error.errors.email);
} else {
console.error("API Error:", error.message);
}
}
// Example usage
handleUpdate({ userId: 1 }, { email: "new.email@example.com" });
Full List of Extractors
Here is a quick reference for all the available type extractors.
ExtractResponseType<T>
: Extracts theresponse
type.ExtractPayloadType<T>
: Extracts thepayload
type.ExtractQueryParamsType<T>
: Extracts thequeryParams
type.ExtractErrorType<T>
: Extracts the union of global andlocalError
types.ExtractGlobalErrorType<T>
: Extracts only the globalerror
type from the client.ExtractLocalErrorType<T>
: Extracts only thelocalError
type from the request.ExtractParamsType<T>
: Extracts the URL parameters type from the endpoint string.ExtractEndpointType<T>
: Extracts the endpoint string literal type.ExtractAdapterOptionsType<T>
: Extracts the options type of the adapter.ExtractAdapterReturnType<T>
: Extracts the raw[data, error, status]
tuple from the adapter.ExtractHasDataType<T>
: Extracts a boolean literal type indicating ifdata
has been set.ExtractHasParamsType<T>
: Extracts a boolean literal type indicating ifparams
have been set.ExtractHasQueryParamsType<T>
: Extracts a boolean literal type indicating ifqueryParams
have been set.
Congratulations!
You know how to leverage Hyper-fetch's type extractors!
- You can deconstruct complex request types into smaller, reusable pieces.
- You know how to use the most common extractors like
ExtractResponseType
andExtractPayloadType
. - You have a full reference list of all available extractors for future use.