-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Ability to extend interfaces declared in ambient modules #280
Comments
I think the new compiler allows this in a good way, because it allows merging of external modules (including between ambient and non-ambient external modules). Let me outline an example and see what you think myLib.ts export module Foo {
export function fn1() { }
} myExtension.ts declare module "myLib" {
export module Foo {
export function fn2(): void;
}
} consumer.ts /// <reference path="myExtension.ts" />
import lib = require('myLib');
lib.Foo.fn2(); // No error Does this meet your scenario? |
Yes, this totally works. |
Feel free to re-open if you run into a scenario this doesn't address. Thanks! |
This doesn't seem to work with the new workflow using @types imports. For example: npm i @types/estree;
// myEsTreeExtension.ts
declare module 'estree' {
interface MyAddon {
}
}
// Some other file.ts
import * as estree from 'estree';
let a: estree.Node; // ERROR: [ts] Module ''estree'' has no exported member 'Node'. Is this a new issue? Or already known? |
The file with the ‘declare module “..”’ needs to be a module as well. I.e. it needs a top level import or export. |
Say I have an awesomely cool library:
And it's so cool that I want people to be able to extend it.
So I add an extension point:
And now anybody can extend it like this:
Except this does not extend the type information. I cannot just do something like:
(trust me, I've tried; you may start laughing now :-)
So instead, in order to make my library extensible, I have to split it into declaration (in the form of .d.ts) and implementation:
And then everybody who wants to extend my library has to do the same.
Just like the good old C/C++ days! Makes you feel young again, doesn't it? :-))
But that's not the end of the PITA.
In addition to all the extenders having to split their extensions, all the users also now have two ways for referencing my library - one for type info, the other for implementation. Check this out:
See how I have two prefixes here? One is "MyCoolLib", the other - "lib".
But it gets weirder. Turns out interfaces can be in the .d.ts file, but classes must be in the .ts file, because they're implementation. So now I have to sometimes write "var x = MyCoolLib.SomeType" and other times write "var x = lib.SomeType", depending on what "SomeType" is.
In real applications, this gets complicated very quickly.
Check out this [almost] real piece of code using Rx:
So the bottom line here is, we have to have an ability to extend interfaces coming from another module. At the very least something like this:
Yes, I do have to write the name and the signature of the function twice, but at least it works.
Ideally, though, I'd like to be able to write it once. Sort of like I do with C# extension methods.
The text was updated successfully, but these errors were encountered: