Description
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 for any
.
interface FunctionalPoint {
new (x: number, y: number) : FunctionalPoint;
x: number;
y: number;
isOrigin(): boolean;
}
type ClassFunction = any;
var FunctionalPoint: FunctionalPoint = <ClassFunction>function (x: number, y: number) {
var self: FunctionalPoint = this;
self.x = x;
self.y = y;
self.isOrigin = () => {
return self.x === 0 && self.y === 0;
}
};
var point1 = new FunctionalPoint(1, 1);
var point2 = new FunctionalPoint(0, 0);
var result = `point 1 is origin: ${point1.isOrigin() }, point 2 is origin: ${point2.isOrigin() }.`;
alert(result);
If the type assertion of <ClassFunction>
on the function is removed, I get this error:
Type '(x: number, y: number) => void' is not assignable to type 'FunctionalPoint'.
Property 'x' is missing in type '(x: number, y: number) => void'.
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.