最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Express - All declarations of 'user' must have identical modifiers - Stack Overflow

programmeradmin1浏览0评论

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 0
Add a comment  | 

4 Answers 4

Reset to default 7

I 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

发布评论

评论列表(0)

  1. 暂无评论