Right now many declaration files take this form:
declare namespace MyLib {
}
declare module 'myLib' {
export = MyLib;
}
However, there doesn't seem to be an equivalent for ES6 modules:
declare module 'myLib' {
export default MyLib; // this works for exporting the default, but other exported items in MyLib are not considered to be named exports of the ES6 module
export * from MyLib; // this is essentially what I'm trying to accomplish
}
so why use export =
then?
@mhegazy Sorry, I didn't understand your comment. Could you clarify?
The export = MyLib
pattern is useful for making a module from a namespace without having to actually redeclare everything. The goal of the issue, in words, would be to allow making an ES6 module from a namespace without having to actually redeclare everything.
We have talked about 1. allowing external modules to access the global namespace (#4166) and 2. extending export *
to namespaces. none has enough traction though.
what is the proposal here?
I don't think #4166 applies here. I'm not trying to access the global namespace. I'm trying to re-export the exported declarations of an existing namespace.
Extending export *
to namespaces might be applicable but it's hard to tell without more context on what you mean.
As far as a proposal, I would suggest new syntax for ambient ES6 module declarations which allows re-exporting declarations from an existing namespace. Let me first illustrate with an example that already works:
declare module "someLib" {
export var a: string;
}
declare module "myLib" {
export * from "someLib";
export var b: string;
}
In that example, export * from "someLib"
re-exports all exports from "someLib". Copied from #2242:
An
export *
declaration can be used to re-export all exports of another module. This is useful for creating modules that aggregate the exports of several other modules.export function transform(s: string): string { ... } export * from "./mod1"; export * from "./mod2";
An
export *
doesn't re-export default exports or exports with names that are already exported from the current module. For example, thetransform
export in the module above hides anytransform
export in the re-exported modules.
My proposal would be the take that same concept and allow it for namespaces as well:
declare namespace SomeLib {
export var a: string;
}
declare module "myLib" {
export * from SomeLib; // <-- this is the new syntax
export var b: string;
}
Looking at the spec, I don't think there's anything exported from a namespace that can't also be exported from a module. In fact, namespace seems to be a subset of module:
AmbientExternalModuleElement:
AmbientModuleElement
ExportAssignment
export ExternalImportDeclaration
Assuming that's the case, export * from SomeLib
seems reasonable.
The use case for this is to simplify writing declaration files for existing ES6 libraries (see #4337).
(Re)exporting namespaces or interfaces is really reasonable.
You can use the follow style:
a.d.ts
export = class A {
}
index.d.ts
export import A = require('./a')
However, you can't use it in a namespace which is incompatible with scene 3
And it usage is quite limited.
For example, I may define several definiation files, assume the library name is MyLib:
a.d.ts
export function AFunc(): void
b.d.ts
export function BFunc(): void
index.d.ts (MyLib definition)
export * as LibA from './a'
export * as LibB from './b'
index.tests.ts
import * as MyLib from 'MyLib'
MyLib.LibA.AFunc()
MyLib.LibB.BFunc()
index.d.ts (MyLib definition)
export * from './a'
export * from './b'
index.tests.ts
import * as MyLib from 'MyLib'
MyLib.AFunc()
MyLib.BFunc()
index.d.ts (MyLib definition)
declare namespace MyLib {
export * as LibA from './a'
export * as LibB from './b'
}
export = MyLib
index.tests.ts
import MyLib = require('MyLib')
MyLib.LibA.AFunc()
MyLib.LibB.BFunc()
...
Any considerations on this?
I'm trying to expose some of the codebase with es6-modules as a global object. This object is constructed from nested namespaces. The problem is that most of the things to be exposed are in es6 modules and I just can't reexport them from namespace.
Something like the following would be extremely useful:
//foo.ts
export enum Foo {
Foo,
Bar
}
export type TFoo = Foo | undefined;
export const FOO = 'FOO';
//global.ts
export namespace TEST {
export const SOME = 'SOME';
export namespace Nested {
export * from './foo.ts'; //error here
}
}
(re)exporting namespaces using existing export syntax would be helpful.
Exporting
export namespace NameSpace {
export {foo} from './foo'
}
Allowing the above, could it help getting rid of the annoying Export declaration is not permitted in a namespace error?
Would love to logically organise a large component using namespace and still maintain the ability to expose needed members to the outside...
I'm currently using next workaround for interfaces:
import {foo} from './foo'
export namespace NameSpace {
export interface Foo extends foo {}
}
This should work for classes as well, the only drawback is the fact that you need to rename variables.
I would also align typings with small modules while re exporting them in a accumulating bigger module.
Most helpful comment
(re)exporting namespaces using existing export syntax would be helpful.
Exporting
Allowing the above, could it help getting rid of the annoying Export declaration is not permitted in a namespace error?
Would love to logically organise a large component using namespace and still maintain the ability to expose needed members to the outside...