TypeScript:将重载函数的参数转发给支持相同重载语法的 class 构造函数

TypeScript: Forward parameters of overloaded function to class constructor which supports the same overloading syntax

我有一个带有重载构造函数的 class。我还有一个 class 的工厂函数 returns class 的一个实例。此工厂函数也被重载,工厂函数的所有重载语法都与重载构造函数语法匹配。

我现在正在寻找一种方法来 'apply' 调用工厂函数的参数到构造函数调用中,而不必在工厂函数和构造函数之间重复关于扣除参数和工厂函数的类型然后在不同的构造函数语法之间切换并专门调用它们。

澄清以上内容的一些代码:

class X {
   constructor()
   constructor(noOfRows: number, noOfCols: number)
   constructor(noOfRows: number, colNames: string[])
   constructor(????) {
        //Logic here deduct based on the arguments send into the call which version of the constructor is called and properly initialize the X instance
   }


function createX(): X
function createX(noOfRows: number, noOfCols: number): X
function createX(noOfRows: number, colNames: string[]): X
function createX(????): X {
    //Here I rather not touch the arguments at all, but just forward them into the constructor call
    return new X(????)
}

我尝试了几种方法,包括下面的 rest/spread 方法,但 TypeScript 不喜欢这样:

function createX(...args: any[]): X {
    return new X(...args)
}

关于如何(正确)执行此操作的任何建议?

TIA,

保罗

你可以这样做:

class X {
    constructor();
    constructor(noOfRows: number, noOfCols: number);
    constructor(noOfRows: number, colNames: string[]);
    constructor(...args: any[]) {
        // ...
    }
}

interface XConstructor {
    new (...args: any[]): X;
}


function createX(): X;
function createX(noOfRows: number, noOfCols: number): X;
function createX(noOfRows: number, colNames: string[]): X;
function createX(...args: any[]): X {
    return new (X as XConstructor)(...args);
}

(code in playground)

同时不导出 XConstructor
另一个选项:

class X {
    constructor();
    constructor(noOfRows: number, noOfCols: number);
    constructor(noOfRows: number, colNames: string[]);
    constructor(a?: any, b?: any) {
        // ...
    }
}


function createX(): X;
function createX(noOfRows: number, noOfCols: number): X;
function createX(noOfRows: number, colNames: string[]): X;
function createX(a?: any, b?: any): X {
    return new X(a, b);
}

(code in playground)