-
Notifications
You must be signed in to change notification settings - Fork 126
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
Improve Type Declarations #111
Conversation
Edit: This PR used to only make lambda-api compatible with TypeScript's strict mode, but after noticing the existing type declarations weren't so accurate, I also included some improvements in this PR and updated the PR's description. |
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.
This works great! Not sure why the old req/res were optional.
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.
I switched to this fork to get proper TypeScript support for route parameters. Works for me. ✅
@jeremydaly Any chance of seeing this merged? |
use (...errorHandlingMiddleware: ErrorHandlingMiddleware[]); | ||
use(path: string, ...middleware: Middleware[]): void; | ||
use(paths: string[], ...middleware: Middleware[]): void; | ||
use(...middleware: Middleware[]): void; |
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.
I think you can improve this even further by allowing mixing normal middleware with error-handling middleware, cause if I see correctly the library allows it. Something like this, but prettier of course ;P :
type AnyMiddleware = Middleware | ErrorHandlingMiddleware
use(path: string, ...middleware: Middleware[]): void;
use(paths: string[], ...middleware: Middleware[]): void;
use(...middleware: AnyMiddleware[]): void;
This PR is essential to use this library with TS, it fixes incorrectly typed basic functionalities. Let's merge it! |
@@ -36,10 +36,10 @@ export declare interface App { | |||
[namespace: string]: HandlerFunction; | |||
} | |||
|
|||
export declare type Middleware = (req: Request, res: Response, next: Middleware) => void; | |||
export declare type Middleware = (req: Request, res: Response, next: () => void) => void; | |||
export declare type ErrorHandlingMiddleware = (error: Error, req: Request, res: Response, next: ErrorHandlingMiddleware) => void; |
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.
export declare type ErrorHandlingMiddleware = (error: Error, req: Request, res: Response, next: ErrorHandlingMiddleware) => void; | |
export declare type ErrorHandlingMiddleware = (error: Error, req: Request, res: Response, next: () => void) => void; |
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.
Sorry for atomic CR comments, I'm finding things as I develop.
export declare type ErrorHandlingMiddleware = (error: Error, req: Request, res: Response, next: ErrorHandlingMiddleware) => void; | ||
export declare type ErrorCallback = (error?: Error) => void; | ||
export declare type HandlerFunction = (req?: Request, res?: Response, next?: NextFunction) => void | {} | Promise<{}>; | ||
export declare type HandlerFunction = (req: Request, res: Response, next?: NextFunction) => void | any | Promise<any>; | ||
export declare type LoggerFunction = (message: string) => void; |
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.
https://github.com/jeremydaly/lambda-api#adding-additional-detail
export declare type LoggerFunction = (message: string) => void; | |
export declare type LoggerFunction = (message: string, additionalDetail?: any) => void; |
@jalooc, let me know when you think this is ready. |
I'm not TS-savvy enough to say if it'd be possible, but it would be very nice to have api.use(async req => {
req.connection = await createConnection()
next()
})
// ...
api.finally(req => {
return req.connection.close() // Can I have the req.connection type automatically inferred?
}) Does anybody know if it's possible? If not automatically inferred, then maybe a generic type for |
@jalooc You'd want to have the req argument to be typed like interface UserReq extends Response {
userToken: string
}
api.use(req => {
const userReq = req as UserReq // TypeScript accepts this cast without any warning, even in the strictest settings
// do something with userReq.userToken...
}) @jalooc @jeremydaly, I'm happy to apply the suggestions, but can we get this merged in a state not so far from how this PR currently stands? It would still be an incremental improvement in the right direction. Or of course feel free to take over this PR. |
@maxmellen , I haven't found any more problems so far, so if you're willing to accept my change suggestions that'd be great (they just follow the |
So what we're doing with the discrepancies I listed? Another PR? |
Yes, please create a new PR. |
Just as a reference for others reading this thread and having a similar question as I did:
@maxmellen The way you suggested is okay in the short run, but after a while of playing with TS, I found a lot of shortcomings. First of all, you'd quickly sink in the depth of overridden interfaces. What's worse, you'd also have to always remember to manually cast I found an imho better and the proper way to do it: Declaration merging or module augmentation more specifically. Following the example from my question, this would solve it: declare module 'lambda-api' {
interface Request {
connection: SomeType,
}
} and from now on you have a typable |
This PR aims to improve the type declarations to more accurately reflect the documentation in the README as well as allow compilation in strict mode.
It also includes an updated package-lock.json file as a result of me simply running
npm install
. The only differences in that file seem to be values used by newer versions of NPM.