typescript 如何扩展Express.Application的类型以给予app.locals的类型

yzuktlbb  于 2023-05-19  发布在  TypeScript
关注(0)|答案(3)|浏览(165)

在我们的应用程序中,我们向app.locals中添加了相当多的配置对象,这些配置对象将在我们的中间件中使用。

const app = Express();
app.locals = {
  someConfig: config
}

我们目前已经为Request对象提供了自定义的类型,这些类型可以正常工作

declare namespace Express {
  export interface Request {
    featureFlags?: FeatureFlag;
  }
}

我知道locals来自Express。应用程序,所以我尝试了这个,它不工作。

declare namespace Express {
  export interface Application {
    locals: {
      someConfig: config;
    };
  }

  export interface Request {
    featureFlags?: FeatureFlag;
  }
}

有人成功地将类型添加到app.locals中了吗?

huwehgph

huwehgph1#

有点晚了但还是...从快递申报文件看:

declare global {
  namespace Express {
    // These open interfaces may be extended in an application-specific manner via declaration merging.
    // See for example method-override.d.ts (https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/method-override/index.d.ts)
    interface Request {}
    interface Response {}
    interface Application {}
  }
}

只需声明全局命名空间Express并扩展所需的接口。

toiithl6

toiithl62#

不能像以前那样从Application类型定义中扩展局部变量。但是,locals基于expressjs Locals类型,您可以扩展它:

declare global {
  namespace Express {
    interface Locals {
      someConfig: config;
    }
  }
}

提示:如果您使用的是智能IDE(如VScode或其他),则在研究此类内容时会很有帮助,您可以右键单击this.app.locals并选择“Go to type definition”,这就是我发现上述内容的原因。

hwamh0ep

hwamh0ep3#

您可以在node_modules/@types/express-serve-static-core/index.d.ts中找到原始文件声明,而不是使用新的声明文件。然后搜索应用界面。诀窍是在该接口上定义另一个属性,所有路由都可以访问它,类似于locals属性。

export interface Application<
    Locals extends Record<string, any> = Record<string, any> 
> extends EventEmitter, IRouter, Express.Application {
    //Make sure to keep all the others properties on the interface
    locals: Locals 
    db: mongoDb.Db //Here is the db key I've added, and all my routes can access it, just like the locals property.

 ];
}

现在,您可以使用app.db ="whatever you need"为该属性赋值,并使用所有自动完成功能。在路由处理程序或中间件中,您可以使用req.app.db访问它。

相关问题