Title: Proposal: Bundling TS module type definitions · Issue #4433 · microsoft/TypeScript · GitHub
Open Graph Title: Proposal: Bundling TS module type definitions · Issue #4433 · microsoft/TypeScript
X Title: Proposal: Bundling TS module type definitions · Issue #4433 · microsoft/TypeScript
Description: Relates to #3159, #4068, #2568, this branch, and this tool. Goals Bundle declarations for TS projects to allow a library to be consumed with a single TS file, despite being many modules internally. Because of complicated internal module ...
Open Graph Description: Relates to #3159, #4068, #2568, this branch, and this tool. Goals Bundle declarations for TS projects to allow a library to be consumed with a single TS file, despite being many modules internally....
X Description: Relates to #3159, #4068, #2568, this branch, and this tool. Goals Bundle declarations for TS projects to allow a library to be consumed with a single TS file, despite being many modules internally....
Opengraph URL: https://github.com/microsoft/TypeScript/issues/4433
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Proposal: Bundling TS module type definitions","articleBody":"Relates to #3159, #4068, #2568, [this branch](https://github.com/Microsoft/TypeScript/compare/declarations...declarations-moduleOut), [and this tool](https://github.com/SitePen/dts-generator).\n# Goals\n- Bundle _declarations_ for TS projects to allow a library to be consumed with a single TS file, despite being many modules internally. Because of complicated internal module dependencies which would rather not be exposed to the consumer, this should flatten the exported module types as best as it can. (Ideally, completely.)\n# Proposal\n\nWhen all of `--module`, `--out`, and `--declarations` are specified, the TS compiler should emit a single amalgamated `.d.ts` (alongside its single output js file). This `.d.ts` should be flattened compared to a concatenated `.d.ts` file. It should report collisions caused by scoping issues and import aliasing when flattening declarations into a single `declare module`. It should respect access modifiers when generating the DTS (only exporting things explicitly exported and types marked as public). \n\nFor example, given the following set of sources:\n`tsconfig.json`:\n\n``` json\n{\n \"compilerOptions\": {\n \"module\": \"commonjs\",\n \"declarations\": true,\n \"out\": \"mylib.js\"\n }\n}\n```\n\n`a.ts`:\n\n``` ts\nexport * from './b';\nexport * from './c';\n```\n\n`b.ts`:\n\n``` ts\nexport interface Foo {}\n\nexport class Bar {\n constructor() {\n console.log('');\n }\n\n do(): Foo { throw new Error('Not implemented.'); }\n}\n```\n\n`c.ts`:\n\n``` ts\nexport class Baz {}\n```\n\nshould create the `.d.ts`:\n`mylib.d.ts`:\n\n``` ts\ndeclare module \"mylib\" {\n export interface Foo {}\n\n export class Bar {\n constructor()\n do(): Foo\n }\n\n export class Baz {}\n}\n```\n\nrather than:\n`mylib.d.ts`:\n\n``` ts\ndeclare module \"mylib/a\" {\n export * from \"mylib/b\";\n export * from \"mylib/c\";\n}\ndeclare module \"mylib/b\" {\n export interface Foo {}\n\n export class Bar {\n constructor()\n do(): Foo\n }\n}\ndeclare module \"mylib/c\" {\n export class Baz {}\n}\ndeclare module \"mylib\" {\n export * from \"mylib/a\";\n}\n```\n\nand should report a semantic error when the following is done:\n`a.ts`:\n\n``` ts\nexport * from './b';\nexport {Bar as Foo} from './b';\nexport * from './c';\n```\n\nas there will be multiple members named `Foo` (an interface and a class), since `b.ts` has exported interface `Foo`.\n\nWe should also have a semantic error when the following is changed from the original:\nIf we change `c.ts`:\n\n``` ts\nexport class Baz {}\nexport interface Foo {}\n```\n\nit should be an error in `a.ts` (since it's blanket exporting `b` and `c`), and the error should suggest to alias either `c.ts`'s `Foo` or `b.ts`'s `Foo` (or both) when reexporting them in `a`.\n\nInternally, when flattening this aliasing becomes important - we need to track usages of the two original `Foo`'s across the generated `.d.ts` and rename it to the alias created when it is reexported.\n\nUnfortunately, 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:\n\nWe 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 `\u003ctypename\u003e_n` when `n` is the shadowed type number for that type, and renaming the shadowed type name to something else (`\u003ctypename\u003e__n` and 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).\n\nAny 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 `interface` name 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.\n\nSomething I've been considering is also rewriting `namespace`s as `interface`s in the generated `.d.ts` in 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.\n","author":{"url":"https://github.com/weswigham","@type":"Person","name":"weswigham"},"datePublished":"2015-08-25T00:03:18.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":84},"url":"https://github.com/4433/TypeScript/issues/4433"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:d10a76a3-1e81-61cc-f8db-3369a31bc270 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | C2A6:149595:439971:601976:6A637BED |
| html-safe-nonce | e6ad565f942e0f6d95715a7128fd9cc4723efe0072e2b280100464d474971b9f |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJDMkE2OjE0OTU5NTo0Mzk5NzE6NjAxOTc2OjZBNjM3QkVEIiwidmlzaXRvcl9pZCI6IjY3NDM1NDc3MDgyMjA2MDMzNzMiLCJyZWdpb25fZWRnZSI6ImlhZCIsInJlZ2lvbl9yZW5kZXIiOiJpYWQifQ== |
| visitor-hmac | 3770ffb02e5fef6d8189a6624f4a9757d4a3a14ae111bf624cfcbe03af23e6d0 |
| hovercard-subject-tag | issue:102917356 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/microsoft/TypeScript/4433/issue_layout |
| twitter:image | https://opengraph.githubassets.com/dc97e134589bc7feb77a9a964a684bfef84f93fbb84ba4faf486ebd94ee5dc4b/microsoft/TypeScript/issues/4433 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/dc97e134589bc7feb77a9a964a684bfef84f93fbb84ba4faf486ebd94ee5dc4b/microsoft/TypeScript/issues/4433 |
| og:image:alt | Relates to #3159, #4068, #2568, this branch, and this tool. Goals Bundle declarations for TS projects to allow a library to be consumed with a single TS file, despite being many modules internally.... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | weswigham |
| hostname | github.com |
| expected-hostname | github.com |
| None | 4c1de337de00c7969335f8866af41463301071379a3a15fba12e9b85aa6378d6 |
| turbo-cache-control | no-preview |
| go-import | github.com/microsoft/TypeScript git https://github.com/microsoft/TypeScript.git |
| octolytics-dimension-user_id | 6154722 |
| octolytics-dimension-user_login | microsoft |
| octolytics-dimension-repository_id | 20929025 |
| octolytics-dimension-repository_nwo | microsoft/TypeScript |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 20929025 |
| octolytics-dimension-repository_network_root_nwo | microsoft/TypeScript |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | a4df32552e4c631011bdcd4c81cc3d7408664a8b |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width