Skip to content
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

No typings for ctx and env? #1

Open
davej opened this issue Oct 19, 2022 · 4 comments
Open

No typings for ctx and env? #1

davej opened this issue Oct 19, 2022 · 4 comments

Comments

@davej
Copy link

davej commented Oct 19, 2022

This is an awesome lib and I'm getting a ton of value from it. I find myself having to jump through hoops to get things typed properly though. Perhaps I am doing things wrong?

Here is an example of how I'm trying to create a new typedParams middleware to add a downloadParams object. And also adding typings for ctx and env (because otherwise they are any type). Is there a better way to do this?

interface DownloadParams {
  appId?: string;
  appVersion?: string;
}

interface Env {
  R2_BUCKET: R2Bucket;
  ORIGIN_URL: string;
  ENVIRONMENT: "dev" | "prod";
}


type AddCtxAndEnvType<T> = Omit<T, "ctx" | "env"> & {
  ctx?: ExecutionContext;
  env?: Env;
};

type Awaitable<T> = T | PromiseLike<T>;
type TypedMiddleware<T extends (...args) => any> = Handler<
  Awaited<ReturnType<T>> & RouteContext
>;
const typedParams =
  () =>
  async <X extends BasicsContext>(
    ax: Awaitable<X>
  ): Promise<X & { downloadParams?: DownloadParams }> => {
    const x = await ax;
    return Object.assign(x, { downloadParams: x.params as DownloadParams });
  };

const middleware = combine(basics(), typedParams());

const handler: TypedMiddlware<typeof middleware> = async (
  req,
  {
    downloadParams,
    userAgent,
    env,
    ctx,
    waitUntil,
    url,
  }: AddCtxAndEnvType<Parameters<TypedMiddleware<typeof middleware>>[1]>
): Promise<Response> => {
  // ...
}
@qwtel
Copy link
Member

qwtel commented Oct 19, 2022

Hey, I'm glad you're getting value out of it.

There's a createMiddleware function, but I've just realized it is too limited for your case. You could take it as a starting point to make your own middleware factory fn though.. EDIT: Link to function

Both the things you're trying to do should arguably be part of the library itself, but I'm not having any good ideas on how to do this right now.

@davej
Copy link
Author

davej commented Oct 19, 2022

Thanks @qwtel. Can I build upon an existing middleware like the basics middleware? For example, if I wanted to type the route's params using the DownloadParams type. Could I do something like this?

createMiddleware({ downloadParams: {} }, async <BasicsContext>(ax) => {
  const x = await ax;
  return {
    ...x,
    downloadParams: x.params as DownloadParams,
  };
});

@davej
Copy link
Author

davej commented Oct 19, 2022

When I do the above then ax isn't typed:
CleanShot 2022-10-19 at 4 19 30@2x

@qwtel
Copy link
Member

qwtel commented Oct 22, 2022

For example, if I wanted to type the route's params using the DownloadParams type. Could I do something like this?

Yeah, you could create your own copy. The source is pretty short.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants