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

Export the type of what is returned by AsyncRouter #5

Open
henrikra opened this issue Aug 6, 2018 · 1 comment
Open

Export the type of what is returned by AsyncRouter #5

henrikra opened this issue Aug 6, 2018 · 1 comment

Comments

@henrikra
Copy link

henrikra commented Aug 6, 2018

I have situation like this:

// fileA.ts
const router = RestypedRouter<MyAPI>(app);
configureRouter(router);

// fileB.ts
function configureRouter(router: any) { // <-- What type here
  // do stuff with router
}

As you can see from the code I am passing RestypedRouter as parameter to a function because I am doing stuff with it inside the function. But the problem is that I can't get the type for the router.

When I look generated index.d.ts file inside node_modules/restyped-express-async I will see definition like this
image

import * as express from 'express-serve-static-core';
import { RestypedBase, RestypedRoute } from 'restyped';
export interface TypedRequest<T extends RestypedRoute> extends express.Request {
    body: T['body'];
    params: T['params'];
    query: T['query'];
}
export default function AsyncRouter<APIDef extends RestypedBase>(app: express.Express | express.Router): {
    route: <Path extends keyof APIDef, Method extends "GET" | "POST" | "PUT" | "PATCH" | "HEAD" | "DELETE" | "OPTIONS">(path: Path, method: Method, handler: (req: TypedRequest<APIDef[Path][Method]>, res: express.Response) => Promise<APIDef[Path][Method]["response"]>) => void;
    use: any;
    get: <Path extends keyof APIDef>(path: Path, handler: (req: TypedRequest<APIDef[Path]["GET"]>, res: express.Response) => Promise<APIDef[Path]["GET"]["response"]>) => void;
    post: <Path extends keyof APIDef>(path: Path, handler: (req: TypedRequest<APIDef[Path]["POST"]>, res: express.Response) => Promise<APIDef[Path]["POST"]["response"]>) => void;
    put: <Path extends keyof APIDef>(path: Path, handler: (req: TypedRequest<APIDef[Path]["PUT"]>, res: express.Response) => Promise<APIDef[Path]["PUT"]["response"]>) => void;
    delete: <Path extends keyof APIDef>(path: Path, handler: (req: TypedRequest<APIDef[Path]["DELETE"]>, res: express.Response) => Promise<APIDef[Path]["DELETE"]["response"]>) => void;
    patch: <Path extends keyof APIDef>(path: Path, handler: (req: TypedRequest<APIDef[Path]["PATCH"]>, res: express.Response) => Promise<APIDef[Path]["PATCH"]["response"]>) => void;
    options: <Path extends keyof APIDef>(path: Path, handler: (req: TypedRequest<APIDef[Path]["OPTIONS"]>, res: express.Response) => Promise<APIDef[Path]["OPTIONS"]["response"]>) => void;
    head: <Path extends keyof APIDef>(path: Path, handler: (req: TypedRequest<APIDef[Path]["HEAD"]>, res: express.Response) => Promise<APIDef[Path]["HEAD"]["response"]>) => void;
};

As you can see the return type of AsyncRouter is NOT exported.

🍏 Solution
Export return type as type. Add something like this to the types

export interface InternalRouter<APIDef extends RestypedBase> {
  route: <Path extends keyof APIDef, Method extends "GET" | "POST" | "PUT" | "PATCH" | "HEAD" | "DELETE" | "OPTIONS">(path: Path, method: Method, handler: (req: TypedRequest<APIDef[Path][Method]>, res: express.Response) => Promise<APIDef[Path][Method]["response"]>) => void;
  use: any;
  get: <Path extends keyof APIDef>(path: Path, handler: (req: TypedRequest<APIDef[Path]["GET"]>, res: express.Response) => Promise<APIDef[Path]["GET"]["response"]>) => void;
  post: <Path extends keyof APIDef>(path: Path, handler: (req: TypedRequest<APIDef[Path]["POST"]>, res: express.Response) => Promise<APIDef[Path]["POST"]["response"]>) => void;
  put: <Path extends keyof APIDef>(path: Path, handler: (req: TypedRequest<APIDef[Path]["PUT"]>, res: express.Response) => Promise<APIDef[Path]["PUT"]["response"]>) => void;
  delete: <Path extends keyof APIDef>(path: Path, handler: (req: TypedRequest<APIDef[Path]["DELETE"]>, res: express.Response) => Promise<APIDef[Path]["DELETE"]["response"]>) => void;
  patch: <Path extends keyof APIDef>(path: Path, handler: (req: TypedRequest<APIDef[Path]["PATCH"]>, res: express.Response) => Promise<APIDef[Path]["PATCH"]["response"]>) => void;
  options: <Path extends keyof APIDef>(path: Path, handler: (req: TypedRequest<APIDef[Path]["OPTIONS"]>, res: express.Response) => Promise<APIDef[Path]["OPTIONS"]["response"]>) => void;
  head: <Path extends keyof APIDef>(path: Path, handler: (req: TypedRequest<APIDef[Path]["HEAD"]>, res: express.Response) => Promise<APIDef[Path]["HEAD"]["response"]>) => void;
}

⚠️ Workaround:
My current workaround is just to copy paste the code above to my own source code. But this is not maintainable because if the type changes in Restyped library I have change my local source code too which is not idea.

👑 Please tell me if you have any questions and tell me if this is clear for you 👍

@ianmartorell
Copy link

Hey, I know it's been two years but if you're still interested in this, I forked this package to ianmartorell/restyped-express and I also want to use the function type in my code, but I'm not sure what's the best way to go about adding it. Any help would be appreciated.

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