Как лучше сделать экспорт класса, чтобы вызывать его как функцию?

Чтобы сделать экспорт класса таким образом, чтобы его можно было вызывать как функцию, в TypeScript можно использовать декоратор @ в сочетании с специальным ключевым словом newable. Декоратор @ позволяет добавлять дополнительную функциональность к классу и его методам, а ключевое слово newable указывает на то, что класс может быть вызван как функция.

Вот пример, как можно реализовать экспорт класса, чтобы его можно было вызывать как функцию:

// file: MyClass.ts
@newable
export class MyClass {
  constructor(public name: string) {}
  
  greet() {
    console.log(`Hello, ${this.name}!`);
  }
}

// file: index.ts
import { MyClass } from './MyClass';

const myInstance = new MyClass('John');
myInstance.greet(); // выводит: "Hello, John!"

const myInstance2 = new MyClass('Jane');
myInstance2.greet(); // выводит: "Hello, Jane!"

function newable(target: any) {
  return function() {
    return new target(...arguments);
  }
}

В этом примере класс MyClass экспортируется с использованием декоратора @newable, который делает класс вызываемым как функцию. При создании экземпляра класса с использованием оператора new, конструктор MyClass будет вызван и создаст новый объект. Теперь можно вызывать методы этого объекта, например greet(), как и у любого другого экземпляра класса.

Декоратор newable применяется к классу MyClass и возвращает функцию-обёртку, которая создает новый экземпляр класса при вызове. Функция-обёртка принимает все аргументы, переданные при вызове класса. Это позволяет передавать значения параметров конструктора класса при вызове класса как функции.