You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Say I'm writing a declaration file for an external library that both exposes a global and supports CommonJS. According to the handbook I would write that like this:
// Either
import x = require('zoo');
x.open();
// or
zoo.open();
The problem is that while the above would compile when using external modules, at run-time it would fail since the "zoo" identifier doesn't actually exist. Is there any way to write declaration files such that you can split them into two separate files (one for internal, one for external) so that you only reference the one you intend on using but not actually duplicate the definitions in those files? For example
// zoo.d.ts
declare module "zoo" {
export = zoo;
}
// zoo-internal.d.ts
/// <reference path="zoo.d.ts" />
module zoo {
// this doesn't work but illustrates what I'm trying to accomplish
import zoo = require('zoo')
export = zoo;
}
Or any thoughts on another way to accomplish the same goals in a single file?
The compiler can not force the existence of js code. Simply because it does not know about it. If you are exposing an internal module, then it is the responsibility of your users to load the library js code, either through a script tag, bundling it at build time or using a resource loader. This is the same in the case of most libraries definitions, say jquery.d.ts, you need to include the .js file independently from the definition.
If your library is available in two modes, e.g. a universal module implementation, then I would recommend releasing two declaration files, one for each mode just to avoid confusion. This is what we did for typescript package definition. What the compiler does not support is generations both files in the same compilation, namely multi file external modules, which is a highly requested feature and I would expect us to support it in the future. For the time being we worked around by copying the file and addng the export statement. There are a few tools out there that can help you out.
If however your module have global side effects, then that is a different issue. The language does not support modeling of these global side effects and I would argue that it should not be added in the future either.
The compiler can not force the existence of js code.
To be clear, I wasn't asking for this.
If your library is available in two modes, e.g. a universal module implementation, then I would recommend releasing two declaration files, one for each mode just to avoid confusion.
This is exactly what I was asking about. I don't mind releasing two declaration files. The problem, currently, is that both declaration files have 99% duplication. I'm asking for a language feature which will remove this duplication. As one possible example of such a language feature, you could allow an internal module declaration to import an external module declaration and then append the external module's exports to that of the internal module's. (see my example in the original post)
What the compiler does not support is generations both files in the same compilation
I'm talking about writing declarations for pre-existing libraries, not for libraries written in TypeScript.
Unfortunately that gets back to the original issue, which is that by referencing zoo.d.ts you get both the external module and the internal module.
Is there any reason that the export * from "identifer" can't be allowed within an internal module declaration? Presumably it just re-exports the existing members.
The problem really is you can not mix external into internal. think of internal modules as namespaces, so they are just simple IIFE's that have a name.. external modules require loading and dependency resolution and detection. so when i use the internal module zoo, would that be rewritten as a require call?
Activity
jbrantly commentedon Feb 12, 2015
It was brought to my attention that the TypeScript team actually solves this internally by scripting. https://github.com/Microsoft/TypeScript/blob/42c05453bd5f2b1c4e75cd2fff1d2b55434119c0/Jakefile#L352-L356
Any plans on supporting it at the language level?
mhegazy commentedon Feb 16, 2015
The compiler can not force the existence of js code. Simply because it does not know about it. If you are exposing an internal module, then it is the responsibility of your users to load the library js code, either through a script tag, bundling it at build time or using a resource loader. This is the same in the case of most libraries definitions, say jquery.d.ts, you need to include the .js file independently from the definition.
If your library is available in two modes, e.g. a universal module implementation, then I would recommend releasing two declaration files, one for each mode just to avoid confusion. This is what we did for typescript package definition. What the compiler does not support is generations both files in the same compilation, namely multi file external modules, which is a highly requested feature and I would expect us to support it in the future. For the time being we worked around by copying the file and addng the export statement. There are a few tools out there that can help you out.
If however your module have global side effects, then that is a different issue. The language does not support modeling of these global side effects and I would argue that it should not be added in the future either.
jbrantly commentedon Feb 17, 2015
Mohamed Hegazy (@mhegazy) Thanks for your response.
To be clear, I wasn't asking for this.
This is exactly what I was asking about. I don't mind releasing two declaration files. The problem, currently, is that both declaration files have 99% duplication. I'm asking for a language feature which will remove this duplication. As one possible example of such a language feature, you could allow an internal module declaration to import an external module declaration and then append the external module's exports to that of the internal module's. (see my example in the original post)
I'm talking about writing declarations for pre-existing libraries, not for libraries written in TypeScript.
jbrantly commentedon Feb 23, 2015
It seems like #1983 might provide a solution to this if it allowed usage within an internal module declaration. For example:
mhegazy commentedon Feb 23, 2015
I am afaraid that is not going to work either.
export * from "mod"are only allowed in external modules.You can do the oposite though:
jbrantly commentedon Feb 23, 2015
Unfortunately that gets back to the original issue, which is that by referencing
zoo.d.tsyou get both the external module and the internal module.Is there any reason that the
export * from "identifer"can't be allowed within an internal module declaration? Presumably it just re-exports the existing members.mhegazy commentedon Feb 23, 2015
The problem really is you can not mix external into internal. think of internal modules as namespaces, so they are just simple IIFE's that have a name.. external modules require loading and dependency resolution and detection. so when i use the internal module zoo, would that be rewritten as a require call?
jbrantly commentedon Feb 23, 2015
Keep in mind I'm only talking about declaration files here for an external module written in UMD.
jbrantly commentedon Feb 23, 2015
For clarity: "third party library written in UMD"
mhegazy commentedon Feb 23, 2015
We need a proposal for this one. I understand that this is a pain point, and we need a solution.
mhegazy commentedon Feb 22, 2016
closing in favor of #7125