问题
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