javascripttypescripttype-declaration

How to declare a module in TypeScript with an object as default export


In a TypeScript project, I would like to use a third-party library that does not provide type definitions. So I need to come up with my own module declaration. What the module basically exports looks like this:

const foo = {
  bar () {
    return 23;
  }
};

module.exports = foo;

So, the question now is how to come up with the module declaration. First of all, it's obvious that the module uses a default export, not a named one. This default export is an object, which has methods. So I tried this:

declare module 'foo' {
  export default {
    bar(): number;
  };
}

However, the TypeScript compiler complains that:

The expression of an export statement must be an identifier or a qualified name in an ambient context.

What does this mean? Using bar, I have used an identifier, haven't I? And what does "qualified name in an ambient context" mean?


Solution

  • Using bar, I have used an identifier, haven't I?

    The error is talking about the object of the export clause. While you have used bar as an identifier, specifically as a method name, you are not exporting that identifier, you are exporting an object literal contains it.

    In

    declare module 'foo' {
      export default {bar(): number};
    }
    

    the identifier bar refers to a method of the exported value not the exported value itself.

    To correct this, write

    declare module 'foo' {
      const foo: {bar(): number};
      export default foo;
    }
    

    A qualified name is one which is referred to by qualifying its name with its enclosing scope as in a.b

    declare module 'foo' {
      namespace ns {
        const foo: {bar(): number};
      }
      export default ns.foo; 
    }