简体   繁体   English

Node.js 全局变量和 TypeScript

[英]Node.js global variable and TypeScript

I need to have some strongly-typed global variables.我需要一些强类型的全局变量。

As mentioned here: Extending TypeScript Global object in node.js , in order to add fields to the global variable I need to add adts file that extends the Global interface that's specified in node.d.ts.如此处所述: Extending TypeScript Global object in node.js ,为了向global变量添加字段,我需要添加扩展 node.d.ts 中指定的Global接口的 adts 文件。

Also, as Basarat mentioned:另外,正如 Basarat 提到的:

Your file needs to be clean of any root level import or exports.您的文件需要清除任何根级导入或导出。 That would turn the file into a module and disconnect it from the global type declaration namespace.这会将文件变成一个模块并将其与全局类型声明命名空间断开连接。

Now, I need to have fields on the Global interface whose types are custom interfaces that I created:现在,我需要在Global接口上有一些字段,这些字段的类型是我创建的自定义接口:

declare namespace NodeJS{
    interface Global {
        foo: Foo
        bar: Bar
    }
}

I'm extremely not willing to use the any type.我非常不愿意使用any类型。

I can move/copy all the interface declarations to this declaration file, but it's a bad solution for me, since both Foo and Bar in turn, aggregate many fields of other interfaces, including third party interfaces like Moment etc.我可以将所有接口声明移动/复制到这个声明文件,但这对我来说是一个糟糕的解决方案,因为 Foo 和 Bar 反过来聚合了其他接口的许多字段,包括 Moment 等第三方接口。

I need a solution for this paradox我需要一个解决这个悖论的方法

Here's an approach.这是一个方法。 I don't know if this is the 'correct' way of doing things, but it works for me with TypeScript 3.7.4.我不知道这是否是“正确”的做事方式,但它适用于 TypeScript 3.7.4。

  1. Assuming your source files live in a folder src , create a new folder src/types and create a file global.d.ts in this folder.假设您的源文件位于src文件夹中,请创建一个新文件夹src/types并在此文件夹中创建一个文件global.d.ts
  2. Author your declarations using one of the following strategies:使用以下策略之一编写您的声明:
    • If you need to import external types into your declaration file, use the following syntax:如果需要将外部类型导入到声明文件中,请使用以下语法:
import { Express } from 'express';

declare global {
  namespace NodeJS {
    interface Global {
      __EXPRESS_APP__: Express;
    }
  }
}
  • If your declaration file does not contain any imports, the above will not work, and you'll need to use this syntax instead:如果您的声明文件不包含任何导入,则上述方法将不起作用,您需要改用以下语法:
declare namespace NodeJS {
  interface Global {
    __CONNECTION_COUNT__: number;
  }
}
  1. Make sure your global.d.ts file (and any other files you might add to src/types ) is picked up by the TypeScript compiler, by adding the following to your tsconfig.json file:通过将以下内容添加到您的tsconfig.json文件,确保您的global.d.ts文件(以及您可能添加到src/types任何其他文件)被 TypeScript 编译器tsconfig.json
{
  "paths": {
    "*": ["node_modules/*", "src/types/*"]
  }
}
  1. Use the global variable as normal inside your code.在代码中正常使用全局变量。
// Below, `app` will have the correct typings
const app = global.__EXPRESS_APP__;

I found this works.我发现这有效。

Have one file that declares the property on the NodeJS.Global interface with the any type.有一个文件,用 any 类型声明 NodeJS.Global 接口上的属性。 This file has to be clean of imports or refrences.该文件必须没有导入或引用。

node.d.ts节点.d.ts

declare namespace NodeJS{
    interface Global {
        foo: any
    }
}

Then in the second file you declare a global variable that has the correct type.然后在第二个文件中声明一个具有正确类型的全局变量。

global.d.ts global.d.ts

import IFoo from '../foo'

declare global {

  const foo:Ifoo

}

This worked for me (node v16.13.2)这对我有用(节点 v16.13.2)

  1. In your root create file types/global.d.ts在您的根目录中创建文件types/global.d.ts
declare global {
    var __root: string
}
export {}

Note that __root declared with var keyword.请注意, __root使用var关键字声明。 It works with let and const too, but in this case __root will have any type.它也适用于letconst ,但在这种情况下__root将具有any类型。 I don't know why;) If someone can explain this it will be great.我不知道为什么;)如果有人能对此进行解释,那就太好了。

  1. Configure your tsconfig.json配置你的tsconfig.json
{
    "compilerOptions": {
        "typeRoots": [
            "types"
        ],
    }
}
  1. Use declared variable in your code在代码中使用声明的变量
// app.ts (entry point)
import path from 'path'
global.__root = path.join(__dirname)
// anyFileInProject.ts
console.log(__root)  // will display root directory

Simple and Easy 简单易行

create a static property in Global class Global类中创建一个静态属性

export class Global {
    static name: string
}

then use it without hesitation 然后毫不犹豫地使用它

export class MyClass {

   constructor() {
      Global.name = 'Wasif'
      console.log(Global.name)
   }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM