1
votes

ES6 Proxy.apply method serves a way to use classes without a "new" keyword.

But on TypeScript, it gives an error "Value of type 'typeof ClassName' is not callable. Did you mean to include 'new'?".

Is there any way to prevent TypeScript errors?

Here is the simple example of it;

class ClassName {
  constructor(anyThing?: any) {
    if (anyThing) {
      // Do something
    }
  }
}

// ES6 Proxy
const CustomName = new Proxy(ClassName, {
  apply: (Target, _thisArg, argumentsList) => {
    return new Target(...argumentsList);
  }
});

// Test ---------
new ClassName("test"); // return ClassName { }

// No error
new CustomName("test"); // return ClassName { }

// Javascript: no error
// TypeScript: error => Value of type 'typeof ClassName' is not callable. Did you mean to include 'new'?
CustomName("test"); // return ClassName { }
2

2 Answers

0
votes

Typescript is not able to understand what your apply function does to the class. You will need to augment the type.

Solution (playground)

class ClassName {
  constructor(anyThing?: any) {
    if (anyThing) {
      // Do something
    }
  }
}

// ES6 Proxy
const CustomName = new Proxy(ClassName, {
  apply: (Target, _thisArg, argumentsList) => {
    return new Target(...argumentsList);
  },
  get: () => { ... }, // Implement static method(s)
}) as typeof ClassName & (() => ClassName) & { staticMethod(): CustomName };

let instance: ClassName;

instance = new ClassName();
instance = new CustomName();
instance = CustomName();
instance = CustomName.staticMethod();
0
votes

Make Proxy callable with Target's static method

class ClassName {
  constructor(anyThing?: any) {
    if (anyThing) {
      // Do something
    }
  }

  // Forge
  static forge (anyThing?: any) {
    return new ClassName(anyThing);
  }
}

// ES6 Proxy
const CustomName = new Proxy(ClassName, {
  apply: (Target, _thisArg, argumentsList) => {
    return new Target(...argumentsList);
  }
}) as typeof ClassName & typeof ClassName.forge;

let instance: ClassName;

instance = new ClassName();
instance = new CustomName();
instance = CustomName();