2
votes

Here is my previous question

TL;DR: I'm trying to declare types for my NodeJS global variables (which I'm setting up in the before hook), so the TypeScript can recognize it.

My wdio.conf:

...
let chai = require('chai');
let { customAssert } = require('../helpers/customAssert');
...
before: async function (capabilities, specs) {
        // I have accomplished to declare types for this variables thanks to the answer in the previous question
        global.foo = "bar"
        global.expect= chai.expect;
        global.helpers = require("../helpers/helpers");
        // ... etc.
        // ... etc.
        // However I'm stuck with this:
        chai.use(customAssert);
        global.customAssert = chai.customAssert;
    },

Because customAssert is my own plugin I need to "add" it to the Chai with use. After this I can use my custom assert logic like this: chai.customAssert.

Of course I don't want to import both modules in the each test and "plug-in" my custom assert very time. That's the reason why I'm declaring it in the global scope.

However I have no idea how to convince the TypeScript that customAssert can be a part of the chai after I will plug it in with chai.use

global.d.ts

import chai from "chai";
import customAssert from "../helpers/customAssert"

declare global {
  const foo: string;
  const expect: typeof chai.expect;
  const helpers: typeof import("../helpers/helpers");

  const customAssert: typeof chai.customAssert // Property 'customAssert' does not exist on type 'ChaiStatic'. Duh...

  namespace NodeJS {
    interface Global {
      foo: typeof foo;
      expect: typeof expect;
      helpers: typeof helpers;
      customAssert: typeof customAssert; // Will not work but let it be
    }
  }
}

Property 'customAssert' does not exist on type 'ChaiStatic' because I need to add my plugin to Chai by chai.use first.

However I can't do this in the global.d.ts because Statements are not allowed in ambient contexts.

How do I declare a type of the NodeJS global variable which will exist in the scope of the chai only after I will plug it in?

1
I'ts just a shot in the dark but maybe you can try something like declaring customAssert as an extension (extends) of Chai (not sure if this is the right approach) - Yuriy Gerasimovich
Assuming you are using @types/chai, a good way to start this would be to look at the existing typing for chai, determine how they define a plugin, then augment the chai module to include your custom plugin. Fumbling with globals is not the way to go - smac89
@smac89 thank's for the comment. Do you think your suggestion should be combined with zishone's answer or it's a an another approach? - anotheruser

1 Answers

0
votes

In your types root create this folder structure

.
└── chai/
    └── index.d.ts             

index.d.ts

declare module Chai {
  interface ChaiStatic {
    customAssert: any;
  }
}