Search code examples
typescripttypescript-typingstype-declaration

Type properties of merged interface declaration


I'm having trouble extending the interfaces of third-party libraries globally, as importing other files in a root-level will cause the declaration file to not be global anymore.

Here's an example:

I'd like to add a property "user" of type "MyUser" on Express's Request object. If it was of type MyUser, I could simply do the following:

declare namespace Express {
  interface Request {
    user: string;
  }
}

and then somewhere else:

...
function(..., req: Request, ...) {
  ...
  req.user; //its a string
  ...
}

and everything would work perfectly. However, doing the following does not work:

import MyUser from "../../src/types/MyUser";
declare namespace Express {
  interface Request {
    user: MyUser;
  }
}

because I now have a top-level import. Is there no way to avoid it? What's the point of being able to merge declarations, if you can't even use your own types within them?


Solution

  • If you add an import, your file is a module and thus any definition is local (without imports the file is a legacy script file and everything in it is global).

    To put the interface in the global scope and use imports use declare global

    import MyUser from "../../src/types/MyUser";
    declare global {
        namespace Express {
            interface Request {
               user: MyUser;
            }
        }
    }