typescripttypesmocha.jsshould.js

Same types but still error on global declaration "TS2717: Subsequent property declarations must have the same type with same type."


Version 13.2.1 of the library should produces the following error when compiling with TypeScript 2.7.1 on Node 8.9.1:

node_modules/should/should.d.ts(237,5): error TS2717: Subsequent property 
declarations must have the same type.  Property 'should' must be of type
 'Assertion', but here has type 'Assertion'.

I.e. pointing to this line in the type definition file: https://github.com/shouldjs/should.js/blob/9748ae607f80fbf544d4bb67db8e1e014de2301f/should.d.ts#L237

There is also an issue in the should.js github repository where this has previously been discovered and thought to be solved.

Simplified error producing file

Below is a simplified version of the real file which produces the same error:

declare namespace should {

  interface Assertion {
    assert(expr: boolean): this;
    fail(): this;
  }
}

declare global {
  interface Object {
    should: should.Assertion;
  }
}

export as namespace should;

export = should;

Quick-fix

A simple solution would be to just skip the global declaration. This would satisfy my own use-case of the library but as the library is currently intended to allow this use-case it does not seem like an ideal scenario.

Question

Why does this declaration not work? And what would instead be a valid declaration?

EDIT

Test related dependencies, some touching global type definitions and potentially clashing.

{
      "devDependencies": {
        "@types/chai": "^4.1.2",
        "@types/chai-as-promised": "^7.1.0",
        "@types/mocha": "^2.2.48",
        "@types/proxyquire": "^1.3.28",
        "@types/request-promise": "^4.1.41",
        "@types/sinon": "^4.1.3",
        "@types/sinon-chai": "^2.7.29",
        "@types/supertest": "^2.0.0",
        "chai": "^4.0.0",
        "chai-as-promised": "^7.1.1",
        "chai-things": "^0.2.0",
        "mocha": "^3.4.2",
        "nyc": "^11.4.1",
        "proxyquire": "^1.8.0",
        "should": "^13.2.1",
        "sinon": "^4.2.2",
        "sinon-chai": "^2.14.0",
        "sinon-mongoose": "^2.0.2",
        "supertest": "^1.2.0"
      }
 }


Solution

  • If a definition has already assigned the Assertion interface to Object.should globally (which it must have if you are told you are making a subsequent declaration)...

    And if you have extended the original Assertion interface....

    Then you don't need to re-specify the interface in a global declaration.

    Why?

    When you write multiple interface definitions within the same common root, they all contribute to a single type. That means your additions to an interface are included as if they were within the same code block.

    Errors

    If you get the error you mention, or if you can't see the type information you believe you added to the interface it will be because you haven't managed to hit the same common root, i.e. an interface exists in X.Y.Z but you have added it to X.Y.