I am building a nodeJS app using Flow, and I need to extend the default express annotation for express$Request to accommodate other fields that I tack on, like .user and .session.
unfortunately, when I try to do this and create middleware that accepts this new Request type, Flow freaks out and I'm not sure what I'm doing wrong.
the original code for express from flow-typed is:
declare class express$Request extends http$IncomingMessage mixins express$RequestResponseBase {
....
}
declare type express$Middleware =
((req: express$Request, res: express$Response, next: express$NextFunction) => mixed) |
((error: ?Error, req: express$Request, res: express$Response, next: express$NextFunction) => mixed);
so I thought I would just extend express$Request and then all of my middleware should work with the new properties, right?
declare class web$Request extends express$Request {
user: any,
isAuthenticated(): boolean,
session: {
loginForwardUrl: ?string,
},
}
const authenticationMiddleware: express$Middleware = (
req: web$Request, res, next
): mixed => {
if (req.isAuthenticated()) {
return next();
}
req.session.loginForwardUrl = req.originalUrl;
return res.redirect('/auth/login/google');
}
unfortunately, this yields the super-complex error:
function
This type is incompatible with
union: function type(s): web/src/index.js:113
Member 1:
function type: flow-typed/npm/express_v4.x.x.js:97
Error:
web$Request: web/src/index.js:114
This type is incompatible with the expected param type of
express$Request: flow-typed/npm/express_v4.x.x.js:97
Member 2:
function type: flow-typed/npm/express_v4.x.x.js:98
Error:
web$Request: web/src/index.js:114
This type is incompatible with an argument type of
null: flow-typed/npm/express_v4.x.x.js:98
can anyone explain what's going on here and how to fix it?
thanks!
The error says that an argument/param of type express$Request
(Member 1) or null
(Member 2) was expected, but web$Request
was seen.
Unfortunately, Flow does not support extending/overriding flow/lib types:
https://github.com/facebook/flow/issues/396
What I've begun to do is:
flow-typed install [email protected]
express_v4.x.x.js
from flow-typed/npm/ to flow-typed/ (outside flow-typed/npm/ so it won't be overwritten by future flow-typed installs, and inside flow-typed/ so flow will automatically make declare blah
statements global)Right below the declare class express$Request...
(so it's easy to find and so it's above where it's used inside declare module...
, I put:
declare class express$Request extends express$Request {
user: any;
isAuthenticated(): boolean;
session: {
loginForwardUrl: ?string;
};
}
I do this instead of putting my custom props on the original class so that it's easy to see which props are custom.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With