How to declare additional properties using declaration merging? Without overwriting the module?

雨燕双飞 提交于 2021-01-01 09:23:25

问题


Well I am using express-session, with the typing from definity types (@types/express-session)

I notice that the types don't have anything for custom data in the session fields. Which is not that useful. I wish to extend this to contain (say) userId: number.

The file @types/express-session show it can be done using:

/**
 * This interface allows you to declare additional properties on your session object using [declaration merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html).
 *
 * @example
 * declare module 'express-session' {
 *     interface SessionData {
 *         views: number;
 *     }
 * }
 *
 */

So I created a file named ./src/types/types.ts And put the following in it:

 declare module 'express-session' {
     interface SessionData {
         userId: number;
     }
 }

This "works", in that typescript now sees the correct field. On the other hand everything else exposed by express-sesion is no longer visible, as typescript no longer considers the other module-definition part. Things like import {Session} from "express-session"; now give the error:

TS2305: Module '"express-session"' has no exported member 'Session'.

So how do I extend module definitions?


回答1:


I was facing something similar and it was actually your question pushed me down the right path.

In the end, I created my own file, express-session.merge.ts with the following:

declare module 'express-session' {
    interface SessionData {
        someVal: string;
    }
}
export default 'express-session';

I then included this at the top of my app.ts, but after the express-session import:

import expressSession from 'express-session';
import expressSessionMerge from './express-session.merge';

This will then let you use the custom properties in the session:

req.session.someVal = 'something';



回答2:


Beside @David_46592 method, you can also customise your own request type within a customised Context.

For example, you want to add property UserId. It can be done with the following.

    import { Connection, EntityManager, IDatabaseDriver } from "@mikro-orm/core";
    import { Request, Response } from "express";
    
    export type MyContext = {
      em: EntityManager<any> & EntityManager<IDatabaseDriver<Connection>>;
      req: Request & { session: { userId?: number } };
      res: Response;
    };

Then just import MyContext in your app.ts or index.ts and use it when you create server as below:

     const apolloServer = new ApolloServer({
        schema: await buildSchema({
          resolvers: [Resolvers...],
          validate: false,
        }),
        context: ({ req, res }): MyContext => ({ em: orm.em, req, res }),
      });


来源:https://stackoverflow.com/questions/64846227/how-to-declare-additional-properties-using-declaration-merging-without-overwrit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!