14

I am using TypeScript v1.4.1 and would like to require an external module (in this case "chai") and have it be type checked.

However, I am running into some sort of naming conflict with this code:

/// <reference path="../typings/node/node.d.ts" />
/// <reference path="../typings/chai/chai.d.ts" />
/// <reference path="../typings/mocha/mocha.d.ts" />

var chai = require("chai");

var expect = chai.expect;
var assert = chai.assert;

describe("TEST", () =>
{
   it("true should be true", (done)=>
   {
      expect(true).to.be.true;
      done();
   });
});

With this definition file:

declare module chai {
   ...
}
declare module "chai" {
   export = chai;
}

Compiling gives these errors:

test/test.ts(5,5): error TS2300: Duplicate identifier 'chai'.
typings/chai/chai.d.ts(6,16): error TS2300: Duplicate identifier 'chai'.

It seems my only option is rename my chai variable name in test.ts. That seems clunky AND won't type check the use of the renamed chai variable.

Any advice?

2 Answers 2

17

Use the import keyword with require instead of var

import chai = require('chai');

And compile with --module commonjs if you're not already

Or, if for some reason you don't want the test code to be an external module, adding a type annotation will preserve type checking.

var c: typeof chai = require("chai");
Sign up to request clarification or add additional context in comments.

4 Comments

If I do that I can't use --out because this file becomes an external module according to TypeScript: a top level import or export statement makes the file an external module.
I updated my answer to include another option, though you'll still have to rename the variable. It might be helpful for you to include some more info about how you're bundling the code and running the tests because it's not clear to me why you would want to use --out.
Thank you. We found that :typeof option and it works. Let me pick your brain a little though... It is our understanding that if we do no use the --out compile flag, then all our files will be compiled as external modules. Is that true?
Yes that's true. If you're runtime (e.g. node, requirejs) includes a module loader, that seems like the desired behavior.
0

Since TypeScript 3.9 Beta was released it's possible to use require with typing

Example:

const {someValue} = require('fs')

"TypeScript now automatically detects the types of imports you’re using to keep your file’s style clean and consistent."

ref. https://devblogs.microsoft.com/typescript/announcing-typescript-3-9-beta/

1 Comment

What does it mean, to "to keep your file’s style clean and consistent"? I'm not sure if it has actually started to type-check require, because nothing changed for me after updating to 3.9.9.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.