microsoft / TypeScript Public
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: Bundling TS module type definitions #4433
Comments
|
I realize that I've forgotten to propose a way to define the entrypoint module (as is possible in #4434), and I suppose that warrants discussion, too. The entrypoint is the location which (in the above example) TS considers the 'top level' for flattening types (in this example, On the other hand, rather than add a new compiler flag, we could consider all files specified as 'root' files as entrypoints when compiling with |
|
I'm generally in favour of this proposal. I think this feature would help to formalise the idea of a project in Visual Studio (i.e. types defined in namespaces compiled into a a single output file, that can then be referenced by other projects). One of the problems with a single output file is that it makes life difficult when debugging in the browser. See #192 (comment). Ideally something can be worked out for that as well. |
|
#3159 implements most of this proposal, though it restricts it to ES6 or commonjs modules, uses slightly different terminology for tsc command line flags. and omits the type flattening aspect of this proposal. At the very least, it's probably an excellent starting point for talking about this. |
|
some notes from doing this for Angular:
|
|
We can't drop our current |
|
What is the current state of this issue? |
|
It is still in discussion. we have a PR for it, but there are still some open questions. |
|
Can you point to this pull request? |
|
I think that d.ts bundle works very nice, see angular#5796. Thanks a lot for it. |
|
I jumped to/from many issues regarding this "theme". Is this the right one where discuss? In my opinion the compiler should be able to produce also separate bundles, like this: {
"...": "...",
"moduleDeclarationOutput": "./modules",
"modules": {
"module-a": {
"from": "./src/module-a/index.ts"
},
"module-b": {
"from": "./src/module-b/index.ts"
}
}
}having then in |
|
requesting an update on this please |
|
nothing done since last update. no plans to do anything for TS 2.0 at this point. |
|
@weswigham What do you think would be a best strategy in light of this? Would you recommend building a custom TypeScript with your PR? |
|
I wouldn't recommend it, no. TBH, with recent changes to allow module On Mon, May 16, 2016, 6:24 PM Matthew James Davis notifications@github.com
|
|
Any other options, then? |
|
Also still looking for support for this. In addition to {
"compilerOptions": {
"module": "commonjs",
"declarations": true,
"out": "./types/lib.js",
"outModule": "@my-org/example-package"
}
}One other alternative to consider would be to declare the module based on the |
|
I wrote a small script to generate a bundle of your project's declarations: #!/bin/bash
mkdir -p out
npx tsc ./src/index.ts --declaration --emitDeclarationOnly --out out/index.js --module amd &&
echo "
declare module 'YOUR_PACKAGE_NAME' {
import main = require('index');
export = main;
}
" >> out/index.d.tsIt outputs to
|
|
Here's my take on it : bundle option with tsc-prog. Faster than others because it bundles in memory, by intercepting emitted ".d.ts" files during the initial build. Nevertheless, this is a complicated issue. Corner cases everywhere: name conflict (with global symbols and local ones), namespaces import and re-export, external libraries, json files, |
|
If the intent is to offer a single "d.ts" for a single-script library, then that is a complicated problem. As a thought, a lot of d.ts files are becoming quite large. Maybe it is not the end of the world to keep the d.ts files laid out as per the default. However, maybe instead introduce a "friend" concept for d.ts files. Idea shopping... (so far the ts would only perform syntax validation) Advantages:
Cons: |
|
Hello, Thanks to everyone for the valuable conversations above. I would like to ask whether any method is known for bundling declaration maps, especially when Microsoft’s API Extractor is in use. |
@kripod This forum is for the TypeScript compiler. To ask an API Extractor specific question, please create an issue for its GitHub project: https://github.com/microsoft/rushstack/issues You will need to provide more detail explaining how the declaration maps would be used. Thanks! |
|
For anyone wondering, which of the mentioned solutions works. import dts from "rollup-plugin-dts";
const config = [
// …
{
input: "./my-input/index.d.ts",
output: [{ file: "dist/my-library.d.ts", format: "es" }],
plugins: [dts()],
},
];
export default config;Install the rollup cli: and execute We're even using it with the |
|
For the webpack users, there is also this option via plugin |
Typescript doesn't seem to be able to output type declarations the way I want (-> microsoft/TypeScript#4433), so we'll just have to manually do it.
Relates to #3159, #4068, #2568, this branch, and this tool.
Goals
Proposal
When all of
--module,--out, and--declarationsare specified, the TS compiler should emit a single amalgamated.d.ts(alongside its single output js file). This.d.tsshould be flattened compared to a concatenated.d.tsfile. It should report collisions caused by scoping issues and import aliasing when flattening declarations into a singledeclare module. It should respect access modifiers when generating the DTS (only exporting things explicitly exported and types marked as public).For example, given the following set of sources:
tsconfig.json:{ "compilerOptions": { "module": "commonjs", "declarations": true, "out": "mylib.js" } }a.ts:b.ts:c.ts:should create the
.d.ts:mylib.d.ts:rather than:
mylib.d.ts:and should report a semantic error when the following is done:
a.ts:as there will be multiple members named
Foo(an interface and a class), sinceb.tshas exported interfaceFoo.We should also have a semantic error when the following is changed from the original:
If we change
c.ts:it should be an error in
a.ts(since it's blanket exportingbandc), and the error should suggest to alias eitherc.ts'sFooorb.ts'sFoo(or both) when reexporting them ina.Internally, when flattening this aliasing becomes important - we need to track usages of the two original
Foo's across the generated.d.tsand rename it to the alias created when it is reexported.Unfortunately, to maintain ES6 compatability, while we can warn about this behavior with classes (since it's possible that a developer is unaware they're overriding a prior export), we still need to support it (or do we? The spec leads me to believe that attempting to export multiple members with the same name - even via
export *- is an early syntax error). So it would be nice to have a compiler flag to mark the same kind of thing with classes (or namespaces) as an error, but also do the following by default:We can do automatic name collision resolution, but that can result in unpredictable (or convention-based) public member names... but it must be done, I suppose. We could ignore reexported types since it's appropriate to do so in ES6 (following
export *declarations can override previously defined members? maybe? system works this way at present - but that may just be system relying on transpiler implementers to maintain ES6 semantics), then we would need to create "shadowed" types at the appropriate level in the.d.ts- types whose original public access are overridden by later exports but whose types are still required to describe public function argument or return types. Naming these "shadowed" types could be difficult, but given that they only exist for type information and not for access information, a common (re)naming convention could be a desirable solution. Something akin to<typename>_nwhennis the shadowed type number for that type, and renaming the shadowed type name to something else (<typename>__nand so on so long as the name still exists) if that collides with another exported type. Classes used in this way are rewritten to interfaces in the.d.ts, since a constructor function likely isn't accessible for a shadowed class (at least not at its generated exported type name).Any feedback? There's a few alternatives to what I've suggested here, which is possibly the most conservative approach in terms of ability to error early but supporting ES6 semantics best. It's possible to silently ignore
interfacename collisions and rename those automatically as well, but since they're TS constructs and not ES6, I think it's okay to force more discipline in their usage.Something I've been considering is also rewriting
namespaces asinterfaces in the generated.d.tsin this way to further flatten/unify the types, but this... might? not strictly be needed. I haven't come up with a strong case for it.The text was updated successfully, but these errors were encountered: