-
-
Notifications
You must be signed in to change notification settings - Fork 516
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(core): export the "RequestHandlerOptions" type #1774
fix(core): export the "RequestHandlerOptions" type #1774
Conversation
Thanks for opening this, @christoph-fricke! I think this is the right move. I wonder if we can expose a more developer-friendly type to make annotations of custom handlers/resolvers a bit better. How would you imagine that type to work? 🤔 |
@kettanaito I am not quite sure. I can only think of exporting the type of the http methods, so basically: export type HttpMethod<
Params extends PathParams<keyof Params> = PathParams,
RequestBodyType extends DefaultBodyType = DefaultBodyType,
ResponseBodyType extends DefaultBodyType = undefined,
> = (
path: Path,
resolver: ResponseResolver<
HttpRequestResolverExtras<Params>,
RequestBodyType,
ResponseBodyType
>,
options?: RequestHandlerOptions,
) => HttpHandler; However, for my use-case I would still have to destruct the resolver and options Parameters, because the path is typed stronger based on the OpenApi schema. At least, it is then possible to do provide generics when deconstructing the type: type Resolver = Parameters<HttpMethod<MyParams, MyReqBody, MyResBody>>[1] Alternatively, I think the only option is to make typing the |
Update: I temporarily defined the I am just not to sure about the name |
@christoph-fricke, did you try using the generics of The thing is, your abstraction seems to be entire type-focused. As in, you don't provide any extra functionality to interface OpenApiHandlers<ApiDefinition> {
get: typeof http.get<
PathParamsFromApiDefForPath<ApiDefinition>,
RequestBodyFromApiDefForPath<ApiDefinition>,
ResponseFromApiDefForPath<ApiDefinition>
>
// ...the rest of "http.*" handlers.
}
export const openApi = http satisfies OpenApiHandlers<Def>
openApi.get(path, resolver) One thing that MSW doesn't support right now is the I recall Or even better, this is how you can customize the path: type AnyFunction = (...args: any) => any
type SkipFirst<List extends Array<unknown>> = List extends [
infer _First,
...infer Rest,
]
? Rest
: never
type HttpHandlerWithPath<
ApiDefinition,
P extends Path = PathsFromApiDef<ApiDefinition>,
Params extends PathParams = PathParamsFromApiDefForPath<P>,
RequestBody extends DefaultBodyType = RequestBodyFromApiDefForPath<P>,
ResponseBody extends DefaultBodyType = ResponseFromApiDefForPath<P>,
HandlerType extends AnyFunction = typeof http.get<
Params,
RequestBody,
ResponseBody
>,
> = (path: P, ...args: SkipFirst<Parameters<HandlerType>>) => HandlerType
interface OpenApiHandlers<ApiDefinition> {
get: HttpHandlerWithPath<ApiDefinition>
}
function createOpenApi(): OpenApiHandlers<{}> {
return http
} |
On the
|
@kettanaito Ohhhhh! I tried all sorts of ways to provide generics to This makes the proposed type helper Motivation for my openapi-msw wrapperYou are right that it is mostly just wrapping As you wrote, the biggest goal is to also provide type safety for the path so changes in the spec result in conflicts in the handler definitions. Therefore, it needs a wrapper at the type level as you correctly identified, but also a small runtime wrapper to map paths from the OpenAPI spec. In the OpenAPI spec, path templates1 are delimited by curly braces, e.g. Therefore, the wrapper could either map the string literals at the type level, or stay true to the OpenAPI spec and accept paths with curly braces as arguments, which are converted at runtime before forwarding them to MSW. Currently, I have decided for the small runtime wrapper and embrace the OpenAPI spec - basically being OpenAPI first. If you are interested in this, you can find my work-in-progress solution here. Openapi-ts also generates information about response body provided for each return status. In the future, I might consider a beefed-up version of Footnotes |
100% recommend covering this on the type level. You can use string literal types to cast any expression to any other expression, and this will convert your You're doing great job on this! Keep it up. I have an OpenAPI -> request handlers generator as internal tooling and perhaps you would be interested in joining efforts and polishing it together? If you are, let me know. While |
Welcome to contributors, @christoph-fricke! 👏 |
What has changed`
This PR adds additional exports for the
HttpRequestResolverExtras
andRequestHandlerOptions
to the main package export.Why has this changed?
I am currently in the process of writing a small wrapper around MSW's
http
methods that is supposed to use type definitions generated from an OpenAPI spec with openapi-ts. The goal is to be able to have conflicts in http-handler definitions when they are no longer compatible with the OpenAPI spec. Here is some pseudocode that hopefully provides an idea about my intention with "wrapping msw":I am open for other ideas that make it possible to wrap the http methods without exporting the two additional interfaces. However, this is the only solutions that I found, unless it is somehow possible nowadays to provide generic arguments to
typeof http["get"]"
, i.e.<never, never, never>(typeof http["get"])
.Should we rather export some new type helpers than these additional two interfaces? I open for your suggestions.