Extending TypeScript Global object in node.js

2019-02-05 12:29发布

问题:

I have a node.js app that attaches some config information to the global object:

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

The TypeScript compiler doesn't like this because the Global type has no object named myConfig:

TS2339: Property 'myConfig' does not exist on type 'Global'.

I don't want to do this:

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

How do I either extend the Global type to contain myConfig or just tell TypeScript to shut up and trust me? I'd prefer the first one.

I don't want to change the declarations inside node.d.ts. I saw this SO post and tried this:

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

as a way to extend the existing Global interface, but it doesn't seem to have any effect.

回答1:

I saw this SO post and tried this:

You probably have something like vendor.d.ts:

// some import 
// AND/OR some export

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

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.

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



回答2:

To avoid Typescript claim something like this:

TS2339: Property 'myConfig' does not exist on type 'Global'.

I suggest to define custom types. I do it under src/types/custom.d.ts file in my project:

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

Then I ensure these are considered by Typescript in tsconfig.json file:

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

Now you're safe to use your custom property:

console.log(global.myConfig.a);


回答3:

Putting the following file into our project's root directory worked.

global.d.ts

declare namespace NodeJS {
  export interface Global {
    myConfig: any
  }
}

We're using "@types/node": "^7.0.18" and TypeScript Version 2.3.4. Our tsconfig.json file looks like this:

{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es6"  
    },
    "exclude": [
        "node_modules"
    ]
}


回答4:

The only thing that works for me is this:

// lib/my.d.ts

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

and then using it in other files like so

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

const cwd = global.cdtProjectRoot; // works