-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Strongly typing a JS functional-style "class" #2299
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
Comments
Why do you need |
Thanks, Dan. Of course, using |
Ah, gotcha. First, you probably intend to have a different shape for your class here. An interface with a construct signature generally should only have static members in it as it would be describing the constructor function. Like with your code there you can now legally do interface FunctionalPoint {
x: number;
y: number;
isOrigin(): boolean;
}
interface FunctionalPointConstructor {
new (x: number, y: number) : FunctionalPoint;
}
var FunctionalPoint = <FunctionalPointConstructor><Function>function (x: number, y: number) { ... } That said, there's still not really a better solution here than what you've done. The compiler only allows It's possible we should add a new exception to the assignability rules specifically for this case (assigning void returning functions to construct signatures), as we essentially already have this special case of how void returning functions are newable to handle this pattern but don't allow you to follow through to stronger typing. |
Hi Dan - thanks very much for this excellent explanation. I hadn't considered that side-effect (regarding being able to call new on an instance), and I should have thought to cast down to I do think that it would be nice to be able to close the loop in the type system in this manner. I was following the style used by examples on the Knockout JS tutorial site for this experiment. For example, Because these are samples from a popular library, I expect there is a lot of JS out there that looks just like this and it would be helpful to have a way to completely type it without needing to do unnecessary refactoring to proper TS classes or needing to do a non-obvious double-cast. Plus this would be a nice bone for those who are simply against classes and prefer the JS functional style (though most of those folks don't care for Thanks. |
Yep, makes sense to me. I logged a new issue to capture that language change suggestion in a more concise form. I'll just close this one as by design and it can serve as an additional reference for that one. |
Much appreciated. |
I'm trying to convert a JavaScript functional-style "class" from JS to strongly-typed TS making minimal changes to the code other than adding type annotations. I do not want to use the
class
keyword (this is an experiment to ease a refactoring scenario, not newly-written code). I also want the code to compile correctly using--noImplicitAny
.The following code works as expected and compiles cleanly (in 1.4), however I am "cheating" by using the
ClassFunction
type which is an alias forany
.If the type assertion of
<ClassFunction>
on the function is removed, I get this error:Is there any way to do this without resorting to using
any
or refactoring to use classes? I read through the spec and 4.11 seems to indicate that if there is an apparent construct signature (which I believe the interface FunctionalPoint has), then "the result type of the function call becomes the result type of the operation" - which I believe should be FunctionalPoint, no?Please forgive me if I am being dense on this. Thanks very much.
The text was updated successfully, but these errors were encountered: