Home > Enterprise >  new function constructor that returns another function in typescript
new function constructor that returns another function in typescript

Time:12-30

I have this function in javascript:

function test()
{
  this.list = {};
  return (id) =>
  {
    if (!(id in this.list))
      this.list[id] = {default: 123};

    return this.list[id]
  }
}

const blah = new test();
blah("ok").mykey = "ok";
console.log(blah("ok").mykey);
console.log(blah("ok"));

and I'm trying convert it into typescript format. I understand I'd have to use class, however how do I return a function from class constructor?

I don't want have a additional property myfunc as a function new test().myfunc("ok"):

interface simpleObject
{
  [key:string]: string|number|object;
}
class Test
{
  private list:simpleObject;
  public myfunc(id:string)
  {
    if (!(id in this.list))
      this.list[id] = {default: 123};

    return this.list[id] as simpleObject;
  }
  constructor()
  {
    this.list = {};
  }
}

const blah = new Test();
blah.myfunc("test").mykey = "ok";
console.log(blah.myfunc("test").mykey);
console.log(blah.myfunc("test"))

TS Playground

CodePudding user response:

Why do you want to use new on something that returns a function? Just call the function without new.

You can achieve that by keeping your state in closures instead of using this;

function test() {
  const list: {[id: string]: any} = {};
  return (id: string) =>  {
    if (!(id in list)) {
      list[id] = {default: 123};
    }
    return list[id]
  }
}

const blah = test();

See Live Example

I think this is what you should use. Having said that, the ability to specify what a constructor returns is not yet available but could be in the future.

I could suggest a workaround (from the linked issue above) or this answer but I don't see why you'd want to use that for your case since what I suggested is simpler and there is no need for classes here.

CodePudding user response:

The constructor of a class will return the instance of said class, and that is the intended behaviour. Your use case doesn't really necessitate usage of a class. You can still have your function and use this inside. To tell Typescript what type this is, you can use a reserved parameter:

type ReturnedFunction = (id: string) => string | number | object;
type TestFunction = () => ReturnedFunction;

function test(this: TestFunction): ReturnedFunction {
  // same code as before
}
  • Related