13
votes

The following produces valid, working ES5 but emits the error below. I'm using Typescript 1.7.5 and I think I've read the whole language spec and I cannot figure out why this error is produced.

error TS2349: Cannot invoke an expression whose type lacks a call signature.

a.js (ES5 ambient module with default export)

function myfunc() {
  return "hello";
}
module.exports = myfunc;

a.d.ts

declare module "test" {
    export default function (): string;
}

b.ts

import test = require("test");
const app = test();

b.js (generated ES5):

var test = require("test");
var app = test()
1
What line is this error on? - Cory Danielson
Line 2 of test.ts. at test() - drewlio
BTW, pretty confusing that your post uses the base name "test" for all three of your files. The third file, that imports "./test" and is called "test.ts", is surely actually something else. :) - C Snover
@CSnover I agree it's unclear, so I've edited the file names to a and b. a is an ES5 commonjs module with no preexisting type declaration file. b is typescript consuming a. Also, the require() in b.ts is changed from "./test" to "test" as it should be a string literal for an external ambient module. I'm surprised it worked with "./test" as the relative path to test.js, but it worked. But this is better because it's the recommended way from the Typescript spec. - drewlio

1 Answers

10
votes

module.exports exports a literal value in a CommonJS module, but export default says you are exporting a default property, which is not what your JavaScript code actually does.

The correct export syntax in this case is simply export = myfunc:

declare module "test" {
    function myfunc(): string;
    export = myfunc;
}