GeezerVison is showing github.com — Make variable declarations open ended · Issue #819 · microsoft/TypeScript
Make variable declarations open ended #819DescriptionThis 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. Reacted by Charles Samborski, Chad Retz, Chad Engler, James O'Cull, Matej Drolc, JeroenNelen, John Smart, Erik Krogh Kristensen, Simon Bengtsson, Mike Chamberlain and 8 more Activitydanquirk commented on Oct 6, 2014 It's not clear there's a good way to do this for var that doesn't lead to a lot of unsafe code. It's possible there's a way to do this for classes. It would be helpful to understand why you need to have open ended classes and where open ended interfaces are insufficient. clark-stevenson commented on Oct 6, 2014 clark-stevenson commented on Oct 26, 2014 I seen this again today in a different project.
There was a Core class, and an extension added a new method called to the Core prototype time. Since Time.js is a class, and Core.js is a class. The property time cannot be added to core when the definition for time.d.ts is added.
I frequently come up against this problem and cannot seem to resolve it. I run into the interface suggestion but if that is the case, should classes simply be avoided? lucamorelli commented on Oct 30, 2014 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 saschanaz commented on Oct 30, 2014 joepb commented on Nov 6, 2014 In JavaScript we can extend ECMA classes:
Date.foo = function() {...}
One would expect this to be somehow supported by the TypeScript superset. Reacted by James O'Cull, John Smart, Aidan Steele, monnef, Simon Bengtsson, Haritha Wickremasinghe and David Piepgrass basarat commented on Jun 4, 2015 Proposal
If 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
Dan Quirk (@danquirk)
It would be helpful to understand why you need to have open ended classes and where open ended interfaces are insufficient.
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;
}Reacted by Mike Chamberlain NathanWalker commented on Jul 20, 2015 +1 this is very frustrating to not have at the moment. Please please, need this. Pro commented on Aug 5, 2015 adidahiya commented on Aug 5, 2015 #2957 looks like it will cover the use case for open-ended classes lucax88x commented on Sep 16, 2015 changed the title [-]Make class / variable declarations open ended[/-] [+]Make variable declarations open ended[/+] on Sep 16, 2015John0x commented on Mar 9, 2017 Mohamed Hegazy (@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. mhegazy commented on Mar 9, 2017 import * as Vue from "vue";
declare module "vue" {
export var plugin: any; // my new plugin
}
Vue.plugin; // OK
new Vue(); // OKReacted by Moritz Brandes and Thomas Schiet John0x commented on Mar 10, 2017 Mohamed Hegazy (@mhegazy) thanks, I'll try that out, once I'm home :)
Does it work if you have two different declaration files too?
Original (index.d.ts and my own declaration.d.ts)? mhegazy commented on Mar 10, 2017 Vue declaration comes from the declaration file coming from the Vue npm package. i do not know what is the other one. John0x commented on Mar 10, 2017 icewind commented on Mar 21, 2017 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). mhegazy commented on Mar 21, 2017 classes are extensible through interfaces (instance side), and through namespaces (static side). not sure why is variable declarations merging or not is relevant here. maxlk commented on Jun 22, 2017 Mohamed Hegazy (@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 ns namespace) manast commented on Nov 1, 2017 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? Reacted by James O'Cull and David Rohmer jocull commented on Nov 1, 2017 I have worked around this in particular cases by extended a local interface definition. This is not ideal, but it works like this:
interface ResponseExt extends express.Response {
myNewProperty: string;
}
Then you'd just declare usage of ResponseExt explicitly anywhere you use it, such as a function argument. Again, not my favorite thing, but it's the only workaround I could come up with. manast commented on Nov 1, 2017 James O'Cull (@jocull) yes, but what about methods? I would like to extend a class with new methods as in aspect oriented programming... jocull commented on Nov 2, 2017 nolakara commented on Feb 15, 2018 Reacted by Kagami Sascha Rosylight RyanCavanaugh commented on Jun 24, 2021 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. Reacted by Clark Stevenson
MetadataMetadataDevelopmentNo branches or pull requestsIssue actions
|