我不明白"global"在TypeScript/NodeJS中是如何工作的,它们有什么区别?



我正在阅读如下代码:

import { MongoMemoryServer } from "mongodb-memory-server";
import mongoose from "mongoose";
import request from "supertest";
import { app } from "../app";
declare global {
function signin(): Promise<string[]>;
}
let mongo: any;
beforeAll(async () => {
process.env.JWT_KEY = "asdfasdf";
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
const mongo = await MongoMemoryServer.create();
const mongoUri = mongo.getUri();
await mongoose.connect(mongoUri, {});
});
beforeEach(async () => {
const collections = await mongoose.connection.db.collections();
for (let collection of collections) {
await collection.deleteMany({});
}
});
afterAll(async () => {
if (mongo) {
await mongo.stop();
}
await mongoose.connection.close();
});
global.signin = async () => {
const email = "test@test.com";
const password = "password";
const response = await request(app)
.post("/api/users/signup")
.send({
email,
password,
})
.expect(201);
const cookie = response.get("Set-Cookie");
return cookie;
};

我不明白global.signin函数的用途以及它是如何工作的?我想这与Jest有关,但只要我知道Jest代码应该在具有相同文件名和.test.ts扩展名的__test__文件夹中。但是上面的函数是在应用程序根目录中的setup.ts文件中定义和使用的。

我也看到一些代码如下:

declare global {
namespace Express {
interface Request {
currentUser?: UserPayload;
}
}
}

在我不确定的项目的一些.ts文件中,这些global变量与我上面提到的其他global变量相同还是不同?我很想知道这个global变量是如何工作的?

您共享的这段代码正在使用全局扩充https://www.typescriptlang.org/docs/handbook/declaration-merging.html#global-增强

// Hint typescript that your global object will have a custom signin function
declare global {
function signin(): Promise<string[]>;
}
// Assign value to global.signin
global.signin = async () => { /* implementation */ };

测试文件导入的一个或多个模块("mongoose"、"supertest"、"../app"(可能在某个时刻使用global.signin(或window.signin((或者它们的嵌套导入之一是=>在项目中查找"signin"(。因此,出于测试目的,需要对global.signin进行模拟。然而,仅仅添加global.signin = something就会引发typescript错误,因为signin不是标准的全局变量。这就是declare global发挥作用的地方。它提示typescript,在您的特定上下文中,signin函数应该存在于全局范围中。

节点中运行的JavaScript/TypeScript将尝试解决在global中当前本地作用域中找不到的任何内容(与浏览器在window中的查找方式相同(。您可以全局访问的任何函数或变量(例如setTimeout()(,也可以使用global.作为前缀进行访问。它只是让它变得明确。

代码中发生的事情有两件:

declare global {
function signin(): Promise<string[]>;
}

这里它告诉typescript的类型系统global对象还有一个名为signin的函数。这部分不是必需的,但它是有意义的需要typescript来允许您访问/定义该函数,在JavaScript中您只需定义它。
https://www.typescriptlang.org/docs/handbook/declaration-merging.html提供了CCD_ 19如何工作的一些细节。

global.signin = async () => {
// code ...
};

在这里,它实际上被添加到全局对象中。

在JavaScript非严格模式下,您甚至可以编写(注意缺少var/let/const/global.(

signin = async () => {
// code ...
};

我没有看到signin在代码中的任何地方被使用,所以我不清楚它的原因。只要定义它的文件被加载,你就可以简单地将其称为signin()来调用函数。global.是隐式添加的。

的目的

declare global {
namespace Express {
interface Request {
currentUser?: UserPayload;
}
}
}

更实用的是,在express中,您可能希望向中间件添加的请求添加属性。通过声明Express Request有一个名为currentUser的属性,您就可以进行

app.get((req, res) => {
const user: UserPayload = req.currentUser
...
})

没有抱怨未知属性的typescript。举个例子https://blog.logrocket.com/extend-express-request-object-typescript/

相关内容

  • 没有找到相关文章

最新更新