Skip to content

Strongly typing a JS functional-style "class" #2299

Closed
@nycdotnet

Description

@nycdotnet

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    By DesignDeprecated - use "Working as Intended" or "Design Limitation" instead

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions