-
Notifications
You must be signed in to change notification settings - Fork 0
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
feat: support variadic middleware for routes #85
Conversation
>, | ||
) { | ||
...middlewares: [ | ||
...OneSchemaRouterMiddleware< |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, TIL you can spread a type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, this is a rest, not a spread.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very cool.
z.infer<Schema[Route]['response']>, | ||
R | ||
>, | ||
] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this above type for middlewares
will require 0 to many OneSchemaRouterMiddleware
parameters, followed by exactly 1 required EndpointImplementation
parameter?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@epeters3 Exactly! Previously, I thought this was impossible to model using TS. I was wrong :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Way cool. I think the fact that Typescript is fundamentally a correctness checker and DX tool and not just a necessary part of code compilation like with Java or C, has enabled the Typescript maintainers and community to do some pretty incredible things.
@@ -509,6 +510,105 @@ describe('implementations', () => { | |||
}); | |||
}); | |||
|
|||
describe('using middleware', () => { | |||
test('type errors are caught when using middleware', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is actually making the jest assertions here? Or are we just relying on the @ts-expect-error
directives to act like a unit test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, just the ts-expect-error directives. This pattern is used in many tests in this project.
const mws = middlewares.slice(0, -1) as any[]; | ||
|
||
const implementation = middlewares.at(-1) as any; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What was the reason for having to cast as any here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
middlewares
doesn't narrow enough -- it's typed as roughly Array<Middleware | Implementation>
🎉 This PR is included in version 5.4.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Motivation
Many existing LifeOmic services use the "variadic middleware" style when declaring routes:
Currently, it's very diffuclt to adopt
one-schema
in a service that uses this^ pattern, since it can't be represented in aOneSchemaRouter
without significant refactoring.That changes today! This PR introduces support for this syntax in a non-breaking way, thanks to TypeScript magic:
With this^ change, it will be much easier to adopt
one-schema
in existing services.