-
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
Make variable declarations open ended #819
Comments
It's not clear there's a good way to do this for |
Thanks for your response 👍 In this particular project, there is a Game class in JS https://github.com/photonstorm/phaser/blob/master/src/core/Game.js With its accompanying definition And then there is a totally external plugin It adds "iso" to the existing Game Class. Because the first link Game.js is a Class, it seems logical that the definition is a class. I cannot see how to make it an interface. |
I seen this again today in a different project. There was a I frequently come up against this problem and cannot seem to resolve it. I run into the |
well, especially for definition files may be a useful features, because I see several libraries that when included add members to existing type. I don't know if is good to add this in your own code |
I think classes will be required to be open-ended when browsers support subclassing from Array. https://status.modern.ie/subclassinges6 For open-ended variables, are there some reasons not to do this? declare var x: SomeInterface;
extend x: ExtensionInterface;
//x now becomes SomeInterface + ExtensionInterface
/*
same as
interface X { ... }
interface X { ... }
*/ |
In JavaScript we can extend ECMA classes: |
ProposalIf the following is declared: declare class Foo {
static bar: any;
bas():any;
} It can be extended using another declaration: // Amend Foo
declare class Foo {
static anotherStatic: any;
anotherMember():any;
} Reason
Really for a convinient way to model classes. Currently one needs to rewrite the original definition to make it extensible. This is not simple to explain to someone brand new to TypeScript. declare var Foo : FooStatic;
interface FooStatic { // Static properties
new (): Foo;
bar: any;
}
interface Foo{ // Instance properties
bas():any;
}
// Amend Foo
interface FooStatic {
anotherStatic: any;
}
interface Foo{
anotherMember():any;
} |
+1 this is very frustrating to not have at the moment. Please please, need this. |
👍 |
#2957 looks like it will cover the use case for open-ended classes |
need!!! |
+1 |
Been hitting my head up against this for a while. If we want the community to be able to share and depend on each others' d.ts files, then we will need to be able to extend them. |
+1 |
1 similar comment
+1 |
+100500 |
+1 |
1 similar comment
+1 |
+1 This is extremely useful when you write a "plugin" for some other library that adds methods to their existing classes. I would expect my plugin's |
+1 |
+1 |
Required for
Too much of this will maim TypeScript's advantage over JavaScript for this project. |
Please consider adding this. Extending external JavaScript packages is very painful. Adding new methods to existing prototypes seems impossible. Extending them into new definitions is not practical, as you must then override them in every other case to become a new type. They quickly conflict and become incompatible and awkward to use. This is especially true of objects that "chain" and return themselves. http://stackoverflow.com/questions/37505881/extending-typescript-declaration-files |
@jocull this can be achieved using module augmentation today. see my response in http://stackoverflow.com/questions/37505881/extending-typescript-declaration-files?answertab=votes#tab-top |
+1 |
+1 |
Another library where this would be helpful is jspdf. It exports a class |
+1 |
can you elaborate? |
@mhegazy With Vue 2 you can access Vue plugins by the Vue class instance. For example the cookie plugin would be Vue.cookie Therefore I would have to extend the type declaration for the Vue class, which I can currently not do (as far as I can see) since we can't merge class declarations. |
import * as Vue from "vue";
declare module "vue" {
export var plugin: any; // my new plugin
}
Vue.plugin; // OK
new Vue(); // OK |
@mhegazy thanks, I'll try that out, once I'm home :) Original (index.d.ts and my own declaration.d.ts)? |
Vue declaration comes from the declaration file coming from the Vue npm package. i do not know what is the other one. |
@mhegazy yeah, that's the one I meant with index.d.ts) |
This is sad... Most of modules I'm using(typeorm as example) using class instead of interface in their declaration. I can extend them easily in JS but it is impossible in TS(keep type info + autocomplete). |
classes are extensible through interfaces (instance side), and through namespaces (static side). not sure why is variable declarations merging or not is relevant here. |
@mhegazy Class (instance) may be extended through interface only if it's declared in global namespace. It doesn't work when class is defined in some namespace: declare namespace ns {
declare class Foo { }
declare function getFoo(): Foo;
}
namespace ns {
interface Foo {
bar(): number;
}
}
let foo: ns.Foo = ns.getFoo();
foo.bar(); // Error: Property 'bar' does not exist on type 'Foo' (the same works when removing |
It would be quite interesting to hear from the maintainers of typescript the reason why this issue has not been addressed. Is it there a theoretical standpoint that prevents this for being implemented? Is it that you believe this issue is not important, or easy workarounds are available? Some other reason? Why is this issue still open after 3 years? |
I have worked around this in particular cases by extended a local interface definition. This is not ideal, but it works like this:
Then you'd just declare usage of |
@jocull yes, but what about methods? I would like to extend a class with new methods as in aspect oriented programming... |
@manast Would you mind putting an example here for clarity? |
+1 |
The OP is extremely old here and references a link that doesn't work anymore. In the interim we've added external module augmentation, additional forms of permitted declaration merging, and removed some error cases that made declaration merging less ergonomic. With secure JS runtimes being more common (thus no arbitrary mutation to built-ins) and modules exporting immutable surface area in modern (thus you only can augment exposed endpoints, which are already eligible for declaration merging) I don't think there's any necessary work to do in this area. Open to new suggestions on more targeted areas but it's not clear that "make variable declarations open-ended" is a tractable description or the right path forward. |
This used to be on codeplex and I cannot find a reference here.
https://typescript.codeplex.com/workitem/917
The problem is that I have project.d.ts and lets say that it has a Point class with simple {x,y} properties.
project-plugin-coolvector.d.ts might come along tomorrow, and that Plugin JS might add a z property to the existing Point class.
If project-plugin-coolvector.d.ts attempts to export a Point class with a z property. You get a duplicate error. I looked at the JQuery plugins example on DT but project.d.ts must contain classes, since Point has a constructor.
I see no way of being able to support the direction of the project in this instance.
The text was updated successfully, but these errors were encountered: