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

How to pass dynamic router context type to methods function agruments #524

Open
ericarthurc opened this issue May 12, 2022 · 1 comment
Open

Comments

@ericarthurc
Copy link

So in the example below I am making a new oak router, and then I am using the .get method with takes a path then ...middlwares. In the /:id line, there is a anonymous arrow function with the argument ctx. This ctx object has an infered type that is passed by the .get method, and it is dynamic based on the first path string arugment. So ctx in this case is excepting their to be a parameter object with the key id, which is awesome for type safetly and ide intelligence. The ctx argument also has inferred types that carry to the ctx.respone and ctx.request nested objects and this is great.

The issue is I like to split my routers in one file and my router handlers in a different file, like in the router.get('/', handler) line. The handler function has a ctx argument but now its type is any and looses the inferred router context type. Obviously I can still code but then you kinda loose the point of typescript here, and your fly somewhat blind.

I would normally just create a custom type and pass it to the handler function for the arguments, but Oaks router has a dyanmic type that is determined by the first path argument, so there is no one size fits all type of ctx.

Is there is a way to pass the inferred dynamic type over? I know the docs show the middleware being created right on the .get method like router.get('/:id', (ctx) => {}); but that just makes a lot of messy code. I perfer to seperate my router, middleware, and handlers.

const router = new oak.Router();

const handler = async (ctx) => {};

router.get('/', handler)
router.get('/:id', (ctx) => {});

Thank you! :D

@ericarthurc ericarthurc changed the title How to pass dynamic router context type to methods functional agruments How to pass dynamic router context type to methods function agruments May 12, 2022
@ericarthurc
Copy link
Author

I actually came up with a pretty good generic solution that allows for type compile time type checking.

type oakHandler<T extends string> = (
  ctx: oak.RouterContext<T>
) => Promise<void> | void;

blogRouter.get("/", getBlogList).get("/:id", getBlogById);

const getBlogById: oakHandler<"/:id"> = async (ctx) => {};

This allows me to seperate by code base and I can just pass a path string to on oak.RouterContext and it will preserve type safety and now my ctx on my handler is type aware and also ctx.params is object aware!

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

1 participant