Search code examples
typescripttypescript-typingstypescript-definitions

Rework type definitions for analytics-node


There are type definitions for that library that exposes the class Analytics

So, sources are the next

class Analytics {}

module.exports = Analytics

Types definitions are good, shortly they are

declare namespace AnalyticsNode {
  export class Analytics {}
}

export = AnalyticsNode.Analytics

But after those declarations the only way to use library is with

import Analytics = require('analytics-node')

How can I override types definitions locally to make them work in ES6 import way?

I tried to declare a module

declare module 'analytics-node' {
  // export default
  // export
  // export = 
}

But this doesn't work. (import * as Analytics from 'analytics-node' gets access to function, but no new Analytics raises an error in compiler)

I tried to follow guideline about module class definitions but without luck.


Solution

  • It looks like the problem is in differences between CommonJS(node) and ES implementation of modules.

    There is a flag in TS esModuleInterop that nullifies the difference between the two systems. With that flag, it's possible to have something like import module from 'module' instead of import * as module from 'module'

    Here is a note from github issue by Andrew Fong.

    absent esModuleInterop, the only way to use that syntax is for analytics-node to move to a default ES module export. Here's the thing though -- unless Node itself forces a migration to ES modules, the CommonJS single export remains perfectly valid. There technically isn't anything to fix. esModuleInterop isn't a hacky workaround. It's actually how, AFAICT, the TS devs want us to type these scenarios.