Search code examples
javascripttypescriptnew-operator

typescript: 'new' call to function


Recently I thought of converting a side project of mine into Typescript. But I have trouble with calling functions using new.

I am trying to call a function imported from another file like this:

// Function in 'file.js'
function Foo() {
  this.x = 1;
  this.y = 2;
}
Foo.prototype.set = function() {
   return this.x + this.y;
};
export { Foo };
// Function in another file calling Foo
import { Foo } from './file';
function getSum() {
  let foo = new Foo(); // I got the below error here!!!
  foo.set();
}

When I try to type this, I get this error: 'new' expression, whose target lacks a construct signature, implicitly has an 'any' type..


Looking at the typescript documentation, I understand the call signature should be written as follows:

type SomeConstructor = {
  new (s: string): SomeObject;
};
function fn(ctor: SomeConstructor) {
  return new ctor("hello");
}

But I don't know how to apply the above type to my 'Foo' function. I tried to apply the construct signature to the function but couldn't place it right.

// Function in 'file.js' --> renamed to 'file.tsx'
type FooType = {
  x: number,
  y: number,
};

type FooConstructor = {
  new (): FooType
};

function Foo(this: FooType) { // How do I add FooConstructor to this?
  this.x = 1;
  this.y = 2;
}
Foo.prototype.set = function(): number {
   return this.x + this.y;
};

I couldn't apply it while exporting / importing or during function call either. All of the below throw errors.

export { Foo: FooConstructor };
import { Foo: FooConstructor } from './file';
let foo = new Foo() as FooConstructor;

So should I have to change the Foo function into a class, is that the only possible way to type it?! I see many blogs showing how to type a class. But even with that approach, I got an error saying, Type 'FooType' is not assignable to type 'FooConstructor'.

And I am lost here. Any help is appreciated!


EDIT: My File.ts looks like this now:

I add the declaration in the File.ts file, like this:

type FooType = {
  x: number,
  y: number,
};

declare class Foo {
  constructor();
  x: number;
  y: number;
  setHeader(): number;
}

function Foo(this: FooType) {
  this.x = 1;
  this.y = 2;
}
Foo.prototype.set = function(): number {
   return this.x + this.y;
};

export { Foo };

Solution

  • The only way to solve this situation was to convert the below function to a class:

    function Foo(this: FooType) { // How do I add FooConstructor to this?
      this.x = 1;
      this.y = 2;
    }
    Foo.prototype.set = function(): number {
       return this.x + this.y;
    };
    

    to:

    class Foo() {
      x: number;
      y: number;
      constructor() {
        this.x = 1;
        this.y = 2;
      }
      set (): number {
       return this.x + this.y;
      }
    }