Typescript: export as namespace doesn't support nesting namespaces

Created on 3 Jan 2018  路  5Comments  路  Source: microsoft/TypeScript



I'm using rollup to generate a UMD module from my TypeScript source. It's part of a bigger product, so one component exports to a root namespace (e.g. mylib) and another exports to a namespace nested under that (e.g. mylib.plugins.myplugin). Rollup is generating the necessary UMD logic to walk down from the global scope creating namespaces as needed, but I can't model that in my TypeScript d.ts file.

The export as namespace syntax is working great in the first case, but not the second. It looks like TypeScript doesn't support nested namespaces for this purpose. Is this by design or just an omission?

TypeScript Version: 2.7.0-dev.20180103

Code: Two files, a d.ts containing an export as namespace foo.bar declaration and a script that references it.

declaration.d.ts

export var baz;

export as namespace foo.bar;

app.ts

console.log(foo.bar.baz);

Compile with: tsc .\test.d.ts .\main.ts

Expected behavior: The file compiles correctly to the following JS:

console.log(foo.bar.baz);

Actual behavior: Error

declaration.d.ts(3,24): error TS1005: ';' expected.

If I change declaration.d.ts to use export as namespace foo (and update app.ts as needed), the compilation succeeds.

In Discussion Suggestion

Most helpful comment

My temp workaround is

// SDK.ts
export class SDK {}
export interface SDKOptions {}

// globals.d.ts
import * as sdk from "./SDK";
export as namespace Vendor;
export {sdk}

Results in Vendor.sdk.SDK, which I build by Webpack. Writing export as namespace Vendor.sdk in SDK.ts would be so much better.

What about this:

// SDK.ts
export class SDK {}
export interface SDKOptions {}

// index.ts
import * as _sdk from "./SDK";

export namespace Vendor {
    export import sdk = _sdk;
}

In this case you could avoid making it global and just use it after a normal ES6 import.

All 5 comments

Same issue - trying to augment angular-translate.
It works for moment like this:

import * as moment from 'moment';
export as namespace moment;
export = moment;

however there is no working solution for angular-translate to export it as namespace angular.translate

Is there a recommended workaround for this?

You should be able to use module augmentation instead. Eg, if you want to create angular.translate then:

import * as ng from "angular";
namespace translateInternal {
   // ...
}
export { translateInternal as translate };
declare module "angular" {
    export import translate = translateInternal;
}

My temp workaround is

// SDK.ts
export class SDK {}
export interface SDKOptions {}

// globals.d.ts
import * as sdk from "./SDK";
export as namespace Vendor;
export {sdk}

Results in Vendor.sdk.SDK, which I build by Webpack. Writing export as namespace Vendor.sdk in SDK.ts would be so much better.

My temp workaround is

// SDK.ts
export class SDK {}
export interface SDKOptions {}

// globals.d.ts
import * as sdk from "./SDK";
export as namespace Vendor;
export {sdk}

Results in Vendor.sdk.SDK, which I build by Webpack. Writing export as namespace Vendor.sdk in SDK.ts would be so much better.

What about this:

// SDK.ts
export class SDK {}
export interface SDKOptions {}

// index.ts
import * as _sdk from "./SDK";

export namespace Vendor {
    export import sdk = _sdk;
}

In this case you could avoid making it global and just use it after a normal ES6 import.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

blendsdk picture blendsdk  路  3Comments

DanielRosenwasser picture DanielRosenwasser  路  3Comments

uber5001 picture uber5001  路  3Comments

wmaurer picture wmaurer  路  3Comments

manekinekko picture manekinekko  路  3Comments