Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript default import failing

I am trying to setup a project and run tests with mocha with mjackson/expect library for assertion. My code to be tested is:

// inside src/lib/math.ts
export function sum(a: number, b: number): number {
  return a + b;
}

and my test is as follows:

// inside src/tests/math.tests.ts
/// <reference path="../../typings/main/ambient/mocha/mocha.d.ts" />
/// <reference path="../../typings/main/ambient/expect/expect.d.ts" />

import expect from 'expect';

import {sum} from '../lib/math';

describe('sum', () => {
  it('should add two numbers', () => {
    expect(sum(1, 2)).toEqual(3);
  });
});

I am able to compile the code with tsc using the following command:

find src -name *.ts | xargs tsc --declaration --sourceMap --module commonjs --target es5 --listFiles --outDir .

However when I run mocha from my project directory using the following command:

mocha tests

I see the following error in my tests:

TypeError: expect_1.default is not a function

When I open the compiled version of my math.tests.ts, I see the following line at the top of the transpiled code:

var expect_1 = require('expect');

This is fine and as expected. However, when I look inside the test where expect is called, I see the following line:

expect_1.default(math_1.sum(1, 2)).toEqual(3);

Now this line of code seems wrong. The expect library is bundled as an ES6 module and the expect function is a default export from the module.

However, TypeScript compiler has emitted code into my test where it attempts to access a default attribute on expect_1 which is an import from the expect library. The expect_1 reference itself is the default exported function I need in my tests and not expect_1.default which is invalid.

A point to note is, if I modified my math.tests.ts to import expect using the older require syntax. Everything works fine.

Please help me understand what I am missing.

P.S. I use TypeScript 1.8.2 with Node v4.3.1.

like image 464
codematix Avatar asked Mar 05 '16 09:03

codematix


People also ask

Does TypeScript support import?

With TypeScript 3.8, you can import a type using the import statement, or using import type .

What is allowSyntheticDefaultImports?

When set to true, allowSyntheticDefaultImports allows you to write an import like: ts. import React from "react"; instead of: ts.

Can only be default imported using esModuleInterop flag?

The error "Module can only be default-imported using esModuleInterop flag" occurs when we try to import a CommonJS module into an ES6 module. To solve the error, set the esModuleInterop option to true in your tsconfig. json file.

Does ts not have default export?

The "Module has no default export" error occurs when we try to import as default from a module that doesn't have a default export. To solve the error make sure the module has a named export and wrap the import in curly braces, e.g. import {myFunction} from './myModule' .


1 Answers

It looks like the expect namespace type is wrong in the npm package (@types/expect) You can make small workaround to save type checking:

import * as _expect from 'expect';
const expect = _expect as any as typeof _expect.default;
like image 124
Maciej Bukowski Avatar answered Sep 29 '22 13:09

Maciej Bukowski