Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 851
thorn0 Avatar asked Dec 26 '16 21:12

thorn0


People also ask

Are namespaces global TypeScript?

Namespaces are a TypeScript-specific way to organize code. Namespaces are simply named JavaScript objects in the global namespace. This makes namespaces a very simple construct to use. Unlike modules, they can span multiple files, and can be concatenated using outFile .

How do I use global namespace?

By default, you can reference a globally namespaced class by adding a backslash -- eg $x = new \PDO(...); . Trying to use \ won't change that. If you want to drop the backslash from globally namespaced classes, you need to use each of them specifically.

What is global D TS in TypeScript?

A global library is one that can be accessed from the global scope (i.e. without using any form of import ). Many libraries simply expose one or more global variables for use.


1 Answers

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;
    
like image 63
thorn0 Avatar answered Dec 26 '22 16:12

thorn0