typescriptmomentjstypescript-typingsdefinitelytypedtsd

TypeScript: How can I make an existing namespace global?


I'm trying to stop using TSD for obtaining type definitions in a project that uses many libaries via global variables (the outFile option is used in tsconfig.json if this matters). In particular, it uses the Moment library in this way. Moment provides its own type definitions as part of the NPM package. However, these definitions don't declare anything in the global scope. Note that moment is both a global variable of type moment.MomentStatic and a type namespace at that. Using the NPM package, how can I augment the global scope in such a way that everything starts working as it works now with the old type definitions got from TSD? Namely, moment should be available globally, in any file, as both a variable and as a type namespace. Basically, what I want is something along these lines:

import * as _moment from 'moment';
declare global {
    const moment: _moment.MomentStatic;
    import moment = _moment;
}

This doesn't compile:

[ts] Imports are not permitted in module augmentations. Consider moving them to the enclosing external module.
[ts] Import declaration conflicts with local declaration of 'moment'

Is there a workaround?


Solution

  • Answering my own question. Finally I found a way to augment library typings in an old-school project that uses globals and outFile. We need a separate .d.ts for each library. Examples:

    1. Adding compatibility with globals/UMD to Moment.js. To stay compatible with TypeScript 1.x, Moment's type definitions don't include the export as namespace line. A .d.ts file (named, say, augment.moment.d.ts) that fixes this:

      import * as moment from 'moment';
      export as namespace moment;
      export = moment; 
      
    2. Augmenting the type definitions for AngularJS. augment.angular.d.ts:

      import * as angular from 'angular';
      
      declare module 'angular' {
        interface IRootScopeService {
          $$destroyed: boolean;
        }
      }
      
      export as namespace angular;
      export as namespace ng;
      export = angular;