-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Guidance on writing declaration file for multi-targeted libraries #4337
Comments
I'd love to hear what other people have to say about this - I'm in agreement that things are somewhat broken at present. As a little digression, I've just taken over an app that is built using Browserify + Babel and written in ES6. I'd hoped I'd be able to drop TypeScript into the mix by just having it export ES6 which can then be processed by Babel but found that the definition file story was very wanting indeed. For now I've had to bail on the issue. Thanks for writing this up @jbrantly - hopefully something good will result! |
@johnnyreilly, Is the |
Hi @mhegazy , I can't remember the details offhand. I'll reattempt and report back. - I'll try and give you access to a repo that produces whatever issues I face as well. |
👍 While I haven't looked into things enough to know if the initial proposal is the best solution or not, I've had difficulties working with CommonJS libraries when targeting ES6. A standardized, obvious way of doing things would be a plus. |
I'm trying to use the type definitions for Gulp. Are the only options right now:
? For the 2nd option, if I send PRs to have various definitions updated, will that break applications using older (or even current) versions of TypeScript? This is so confusing. 😞 |
Just a note, I have run into this before when authoring various react related typescript definitions. the approach I have been using, which is similar to @jbrantly's concept, is to use the (somewhat new) /// <reference path="../../../typings/main/ambient/react/index.d.ts" />
declare namespace __MyLib {
export interface ThingProps extends __React.HTMLAttributes {
text: string;
}
export class Thing extends __React.Component<ThingProps, any> { }
}
import MyLibExports = __MyLib;
declare module 'mylib' {
export import ThingProps = MyLibExports.ThingProps;
export import Thing = MyLibExports.Thing;
export default MyLibExports.Thing;
} |
Documentation can be found at https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/declaration%20files/Introduction.md |
It is now possible for a library to hit every type of target that TypeScript supports (module, namespace, and ES6). Currently, writing a declaration file for a library like this can be very challenging. The default today is something like this:
This has a couple issues:
MyLib
which is not actually true. This can lead to runtime errors. (see Create "Global / External-agnostic" declaration files without exposing internal definitions #2018)In the past, regarding item 1, it's been suggested that we split the declarations into two files (one for modules and one for namespaces). This makes sense. I think it also makes sense to extend that concept for ES6 modules. So if you have a library that targets all three, then you will have three mutually exclusive declaration files. Where things then become problematic is with duplicating the declarations in each file (which ideally should not happen). It is impossible to import an ambient module into an ambient namespace. It is possible to use an ambient namespace in an ambient module, but a naive approach to that (as shown in the common case above) violates item 1.
Therefore, I propose this guidance to writing these declaration files.
Unfortunately this is currently hypothetical since you cannot re-export namespace declarations from an ES6 declaration.
I'm proposing this as a baseline for discussion to solve this issue for good. It's possible I'm going down the wrong track or that there is already a better way to handle these cases. It would also be great if we could get some buy-in from the TypeScript language to solve this, if needed.
Some possible ways TypeScript could be improved in this area:
__MyLib
only exists as a namespace and not as a value, either through convention (prefixed with __) or through additional syntax.cc @johnnyreilly @vvakame
The text was updated successfully, but these errors were encountered: