I am making use of express
and passport
in my application, In both packages, there's a user
attribute under the Request
interface. Currently, express
has a user
attribute but no other properties attached to it in the request object, e.g req.user
. I am trying to do a declaration merge (not really sure if this is the right term for it) for express in order to tell typescript that Express.Request.user
has an id
attribute attached to it like so:
declare namespace Express {
export interface Request {
user: {
id: string
}
}
}
At the same time also, passport
has a user
attribute but with the value of Express.User
. When I do that declaration merge above, I get an error that says All declarations of 'user' must have identical modifiers.
Here's the declaration file for passport
.
interface User {}
interface Request {
authInfo?: AuthInfo;
user?: User;
// These declarations are merged into express's Request type
login(user: User, done: (err: any) => void): void;
login(user: User, options: any, done: (err: any) => void): void;
logIn(user: User, done: (err: any) => void): void;
logIn(user: User, options: any, done: (err: any) => void): void;
logout(): void;
logOut(): void;
isAuthenticated(): this is AuthenticatedRequest;
isUnauthenticated(): this is UnauthenticatedRequest;
}
I understand it's because of a mismatch in the interfaces, but how do I overcome this? Any help is welcome. Thank you very much!
I am making use of express
and passport
in my application, In both packages, there's a user
attribute under the Request
interface. Currently, express
has a user
attribute but no other properties attached to it in the request object, e.g req.user
. I am trying to do a declaration merge (not really sure if this is the right term for it) for express in order to tell typescript that Express.Request.user
has an id
attribute attached to it like so:
declare namespace Express {
export interface Request {
user: {
id: string
}
}
}
At the same time also, passport
has a user
attribute but with the value of Express.User
. When I do that declaration merge above, I get an error that says All declarations of 'user' must have identical modifiers.
Here's the declaration file for passport
.
interface User {}
interface Request {
authInfo?: AuthInfo;
user?: User;
// These declarations are merged into express's Request type
login(user: User, done: (err: any) => void): void;
login(user: User, options: any, done: (err: any) => void): void;
logIn(user: User, done: (err: any) => void): void;
logIn(user: User, options: any, done: (err: any) => void): void;
logout(): void;
logOut(): void;
isAuthenticated(): this is AuthenticatedRequest;
isUnauthenticated(): this is UnauthenticatedRequest;
}
I understand it's because of a mismatch in the interfaces, but how do I overcome this? Any help is welcome. Thank you very much!
Share Improve this question asked Feb 27, 2021 at 19:07 thatguythatguy 4101 gold badge9 silver badges27 bronze badges 04 Answers
Reset to default 7I had the same issue - I managed to get it working by adding properties directly to the User
interface instead of Request.user
-
In @types/express/index.d.ts
declare global {
namespace Express {
interface User {
userId: number;
name: string;
email: string;
}
}
}
Check if you have declared/imported duplicated type that have the same props.
I had the same issue and struggled for an afternoon on it as well. I managed to make it work like so in my project:
declare global {
namespace Express {
interface User extends UserDocument {
// A basic field so EsLint does not think it's an empty interface,
// and replace it with some other code which it thinks to be better
// (cause for me, it was replacing automatically the line with
// "type User = UserDocument" which was making Typescript unhappy).
// This field is useless, but that's the only solution I found.
uselessField?: boolean;
}
}
}
// Alternatively, you can also substitute this line declaration with:
// "export type UserD = mongoose.Document & {"
// as seen in the Microsoft starter template: https://github.com/microsoft/TypeScript-Node-Starter
// It works too.
export interface UserDocument extends mongoose.Document {
firstName: string;
lastName: string;
email: string;
// ... etc
}
const UserSchema = new mongoose.Schema<UserDocument>(
{
firstName: String;
lastName: String;
email: String;
// ... etc
},
);
export const User = mongoose.model<UserDocument>("User", UserSchema);
I faced this error when I was trying to create my own interface called Request
.
Typescript also has a built-in Request
interface
The attributes in my interface conflicted with the already existing interface.
In such a case, the solution is to just rename the interface to something that has a low chance of already being defined