在node.js中扩展TypeScript Global对象

时间:2016-01-29 00:17:54

标签: node.js typescript global

我有一个node.js应用程序,它将一些配置信息附加到global对象:

global.myConfig = {
    a: 1,
    b: 2
}

TypeScript编译器不喜欢这样,因为Global类型没有名为myConfig的对象:

  

TS2339:财产' myConfig'类型' Global'。

上不存在

我不想这样做:

global['myConfig'] = { ... }

如何扩展Global类型以包含myConfig或者只是让TypeScript闭嘴并信任我?我更喜欢第一个。

我不想更改node.d.ts内的声明。我看到了这个SO post并尝试了这个:

declare module NodeJS  {
    interface Global {
        myConfig: any
    }
}

作为扩展现有Global界面的一种方式,但它似乎没有任何效果。

8 个答案:

答案 0 :(得分:51)

  

我看到了这篇SO帖子并尝试了这个:

您可能有类似vendor.d.ts的内容:

// some import 
// AND/OR some export

declare module NodeJS  {
    interface Global {
        spotConfig: any
    }
}

您的文件需要 clean 任何根级别importexports。这会将文件转换为模块并将其与全局类型声明命名空间断开连接。

更多:https://basarat.gitbooks.io/typescript/content/docs/project/modules.html

答案 1 :(得分:26)

为了避免使用类似于这样的类型:

  

TS2339:财产' myConfig'类型' Global'。

上不存在

我建议定义自定义类型。我在项目中的src/types/custom.d.ts文件下执行此操作:

declare global {
  namespace NodeJS {
    interface Global {
        myConfig: {
          a: number;
          b: number;
        }
    }
  }
}

然后我确保tsconfig.json文件中的Typescript会考虑这些:

{
  ...
  "files": [
    ...
    "src/types/custom.d.ts"
  ]
}

现在您可以安全地使用自定义属性:

console.log(global.myConfig.a);

答案 2 :(得分:12)

将以下文件放入我们项目的根目录中。

global.d.ts

>>> print(df3.head(4))

   A  B  C  time
0  1  2  3     0
1  1  2  3    15
2  1  2  3    30
3  1  2  3    45

>>> print(df3.tail(4))

     A  B  C  time
476  4  5  6  7140
477  4  5  6  7155
478  4  5  6  7170
479  4  5  6  7185

>>> df3.shape  # (480, 4)

我们正在使用declare namespace NodeJS { export interface Global { myConfig: any } } 和TypeScript "@types/node": "^7.0.18"。我们的tsconfig.json文件如下所示:

Version 2.3.4

答案 3 :(得分:7)

唯一对我有用的是:

// lib/my.d.ts

import Global = NodeJS.Global;
export interface CDTGlobal extends Global {
  cdtProjectRoot: string
}

然后在其他文件中使用它

import {CDTGlobal} from "../lib/my.d.ts";
declare const global: CDTGlobal;

const cwd = global.cdtProjectRoot; // works

答案 4 :(得分:7)

node@16 起,NodeJS.Global 接口 has been removed 支持 globalThis

您可以在模块文件中声明新的全局变量:

declare global {
  var NEW_GLOBAL: string;
}

并在非模块文件(无顶级导入/导出)中为:

declare var NEW_GLOBAL: string;

重要说明:变量必须声明为 varletconst 变量未显示在 globalThis 上。

答案 5 :(得分:5)

对我有用的是:

declare global {
  module NodeJS {
    interface Global {
      myConfig: any;
    }
  }
}

global.myConfig = 'it works!';

使用它的唯一缺点是,您必须关闭ESLint规则@typescript-eslint/no-namespace

为完整性起见,这是我的tsconfig.json

{
  "compilerOptions": {
    "declaration": true,
    "emitDecoratorMetadata": true,
    "esModuleInterop": true,
    "experimentalDecorators": true,
    "forceConsistentCasingInFileNames": true,
    "jsx": "react",
    "lib": ["dom", "es2017"],
    "module": "commonjs",
    "moduleResolution": "node",
    "noEmitOnError": true,
    "noImplicitReturns": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "outDir": "dist",
    "removeComments": true,
    "resolveJsonModule": true,
    "rootDir": "src",
    "sourceMap": true,
    "strict": true,
    "target": "es6"
  },
  "exclude": ["dist", "node_modules"]
}

答案 6 :(得分:3)

使用“命名空间”代替“模块”来声明自定义TypeScript

如果您使用以上任何答案,并且使用的是Typescript的较新版本,您都会对使用“模块” 有所na。您应该考虑使用名称空间。

为了满足这里的要求,您实际上除了扩展Global接口还需要更多。如果您想直接从“ globalThis” 上下文访问它,则还需要使用该类型创建一个常量。

注意::当OP询问对象字面量时,该过程与您在下面看到的相同。不必将“ Debug” 类型用作函数,您只需根据需要定义接口,然后将“ debug:” 更改为myConfig或您想要的任何内容即可。

// typically I'll store the below in something like "typings.d.ts"
// this is because, at least typically, these overrides tend to
// be minimal in nature. You could break them up and Typescript
// will pick them up if you wish.

declare global {
  
  // This is our definition or type for the function.

  // If defining a object you might do something like
  // interface IConfig { a: number, b: number }

  type Debug = (label: string) => (message: any, ...args: any[]) => void;

  // Extend the Global interface for the NodeJS namespace.
  namespace NodeJS {

    interface Global {

      // Reference our above type, this allows global.debug to be
      // to be defined in our code.
      debug: Debug; 

    }

  }
  
  // This allows us to simply call debug('some_label')('some debug message')
  // from anywhere in our Node server/application.
  const debug: Debug;

}

如何使用上述内容

为了完整起见,在此示例中,我们所做的只是定义一个全局变量,以便我们可以记录一条简单的调试消息。这是将方法绑定到全局上下文的方法。

global.debug = (label: string) => (message: any, ...args: any[]) => console.log(message, ...args);

在某些文件中,我们现在可以直接调用全局调试方法并记录我们的消息。

debug('express')(`${req.method}: ${req.url}`);

答案 7 :(得分:0)

  

复制我对another post的回答:

globalThis是未来。

// Way 1
var abc: number
globalThis.abc = 200 // no error

// Way2
declare var age: number
globalThis.age = 18 // no error