2017-06-20 34 views
5

Buduję aplikację nodeJS przy użyciu Flow i muszę rozszerzyć domyślną adnotację ekspresową dla wyrażenia $ Request, aby uwzględnić inne pola, do których się przypisuję, takie jak .user i .session.Rozszerzenie klasy żądania ekspresowego w Przepływie

Niestety, gdy próbuję to zrobić i utworzyć oprogramowanie pośrednie, które akceptuje ten nowy typ żądania, Flow odstaje i nie jestem pewien, co robię źle.

kod oryginalny dla Express z przepływem wpisany jest:

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); 

więc myślałem, że po prostu przedłużyć wyraźnej $ request a następnie wszystkie moje middleware powinny działać z nowymi właściwościami, prawda?

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'); 
} 

niestety, daje super-skomplikowany błąd:

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 

może ktoś wyjaśnić, co tu się dzieje i jak to naprawić?

dziękuję!

Odpowiedz

3

Błąd mówi, że oczekiwano argumentu/parametru typu express$Request (Członek 1) lub null (Członek 2), ale został wyświetlony web$Request.

Niestety Flow nie obsługuje rozszerzenie/nadrzędne przepływu/lib typy:

https://github.com/facebook/flow/issues/396

Co Zacząłem robić to:

  1. flow-typed install [email protected]
  2. Move express_v4.x.x.js z przepływem -typed/npm/do typu flow/(poza typem przepływu/npm/tak, że nie zostanie nadpisane przez przyszłe instalacje typu flow i wewnątrz typu flow/więc przepływ automatycznie spowoduje declare blah oświadczenia globalne)
  3. tuż poniżej declare class express$Request... (więc jest to łatwe do znalezienia i dlatego wyżej, gdzie jest używany wewnątrz declare module..., kładę:

    declare class express$Request extends express$Request { user: any; isAuthenticated(): boolean; session: { loginForwardUrl: ?string; }; }

zrobić to zamiast oddanie moich niestandardowe rekwizyty na oryginalnej klasie, aby łatwo było zobaczyć, które rekwizyty są niestandardowe.

+1

oof, brutalny - szkoda że przepływ będzie wspierać ten lepszy. Dziękuję Ci! – user358829

0

Jeśli chcesz tylko dodać pola do klasy żądania, możesz ją rozszerzyć w ten sposób. Działa na [email protected] i później (nie jestem pewien, kiedy to został wprowadzony):

declare class session$Request extends express$Request { 
    product: ProductDoc; 
    ip: number; // this will not work - error: [flow] number (This type is incompatible with string) 
} 

/** 
* GET /api/products/:uuid - Get product 
* 
* @property {string} req.params.uuid - The unique id of the product. 
*/ 
function get(req: session$Request, res: express$Response) { 
    // retrieve product from DB ... 
    return res.json({ data: req.product }); 
} 
+0

tak, zauważ że @ user358829 już wypróbował to z ich 'web $ Request'. Problem polega na tym, że Flow def dla ekspresowego oprogramowania pośredniego oczekuje wyrażenia 'express $ Request', a nie' web $ Request' –