-
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
Feature suggestion: treat prototype assignments like merging type declarations #4038
Comments
I want:
to have the same output as
Along with the benefits of type checking. I think the scope is much smaller than some of the other proposals. No new keywords: it's basically sugar for something that already works. To make type checking easier, there can be a requirement that the value assigned must be a compile-time constant. The assignment might reference a function, a function or arrow expression, a static method of another class, or null or undefined (thus implementing a "pure virtual" method). It may override a method of a parent class or it may be a new method altogether. |
The request here is to essentially make directly assigning to |
In theory, if it is reasonably achievable in typescript, it solves some of the issues around "natively" supporting Mixins and Traits (as well as Decorators would modify the type declaration, which they don't currently). @danquirk do you think a reasonable proposal has a chance? |
@kitsonk I haven't really chatted with anyone else on the team about this in depth yet so I don't want to make any promises I can't keep :) At first glance this is definitely a bit outside what we normally do as far as flow control based semantics and such but it does serve a real use that many people would benefit from. I wonder how much ES6 classes will eventually obviate the need for direct prototype assignment in new code (obviously that still leaves a ton of existing JS that could benefit from this). Some might argue this sort of code is on the more dynamic side of the world which we generally try to allow but don't always support incredibly well (ex dynamic assignment/expandos typed as |
On the other hand, the work we're doing in the JS intellisense branch to pick up |
@danquirk yes, but you might assuming that ES Classes will support the right sort of design patterns. I for one remain unconvinced that ES Classes will head the direction everyone wants to go, and even then, it might take a while to get something agreed. I know TypeScript is trying to do its best to be "future proof" and not meddle in things that might break in the future, but I suspect having a mechanism of extending the typing of a prototype won't interfere with future standards and get a lot of us who don't believe traditional OO inheritance is the right pattern off your backs. 😉 If we wanted to do composition, or traits, factories, or whatever, we could be the "Wizard of Oz" behind the curtains to ensure that our downstream consumed code was type safe. |
Right, my concern here re:ES6 was not really future incompatibility and just musing on the general ROI of any work here if we expect people to move to ES6 classes in short order. There's definitely some opportunity here for TypeScript to just infer the right thing from a pattern that people are already commonly using, although as far as things like traits and mixins I'd prefer something a little more explicit/declarative than a mess of prototype assignments magicing up a type somewhere. |
@danquirk I would too, but #311 is closed. 😢 The main reason was, if I understand correctly "we are going to wait for ECMAScript to take the lead..." It is hard to wait for TC39 to try to use and deliver other design patterns. But if this sort of "modifying the prototype type" were allowed, I, as a middle man, could produce some of this functionality... I will admit @bryanforbes and I have been doing a lot of thinking about composition, factories, traits and mixins for Dojo 2. While union and intersection types will help us out, being able to modify the type of the prototype, would make it challenging for us, but we would be able to deliver a clean API that allowed use of the pattern without breaking TypeScript. |
We've implemented this for JavaScript, but don't see a need to do it for modern TypeScript code. Many better alternatives exist |
I would like better native support for code of this nature:
The code above works, but has a couple of drawbacks, which I think are resolvable:
The compiler has no way of knowing what
this
pointer should be inimpl1
andimpl2
this
is for functions.Possible syntax:
function impl1() overrides Base.myVirtualMethod {}
function impl1(): this implements Base {}
function impl1() { const this: Base; }
The compiler won't let you define a method by assigning a function, so you must assign to the prototype instead
Possible syntax:
public myVirtualMethod() = impl1; // Parentheses distinguish this from a property assignment.
public myVirtualMethod() = null; // pure virtual method (runtime error to invoke, no compile time check)
Type checking:
impl1(); // Type error: Window does not implement { x: number }
this.y = 1; // Type error: Base does not implement { y: number }
public myVirtualMethod() = impl2; // Type error: Derived1 does not implement { y: number }
impl2.call( new Derived1 ); // Type error: Derived1 does not implement { y: number }
The text was updated successfully, but these errors were encountered: