Как вызвать рекурсивный конструктор в TypeScript? - PullRequest
0 голосов
/ 30 декабря 2018

У меня перегрузка конструктора класса, и я хочу рекурсивно вызывать конструктор в зависимости от предоставленных аргументов.

class Matrix {
    /**
     * Construct a new Matrix given the entries.
     * @param   arr the entries of the matrix
     */
    constructor(arr?: number[][]);

    /**
     * Construct a new Matrix given the size.
     * @param   rows the number of rows (matrix height)
     * @param   cols the number of columns (matrix width)
     */
    constructor(rows?: number, cols?: number);

    constructor(rows: number[][]|number = 0, cols: number = 0) {
        function isMatrixRaw(m: any): m is number[][] {
            // return `true` if m is of type number[][]
        }
        if (isMatrixRaw(rows)) {
            // ...
            // do all the main work here
            // ...
        } else { // typeof rows === 'number' && typeof cols === 'number'
            let m: number[][];
            // ...
            // create a 2D array of numbers, given rows and cols
            // recursively call the constructor with the new 2D array
            // ...
            new Matrix(m) // <-- is this right?
        }
    }
}

Основная работа конструктора выполняется, если аргумент является двухмерным массивом записей, но я также хочу перегрузку: предоставить размер строки и размер столбца (например, new Matrix(2,3)).Если rows и cols являются числами, я хочу создать двумерный массив и затем передать этот новый массив обратно в конструктор.

Как рекурсивные вызовы конструктора работают в TypeScript?Мне звонить new Matrix(), return new Matrix(), this.constructor(), Matrix.constructor() или что-то еще?

1 Ответ

0 голосов
/ 30 декабря 2018

Вы можете вернуть значение из конструктора.Возвращаемое значение будет результатом операции new:

class Matrix {
    public rows: number[][];
    constructor(arr: number[][]);
    constructor(rows: number, cols: number);
    constructor(rows: number[][]|number = 0, cols: number = 0) {
        function isMatrixRaw(m: any): m is number[][] { return m instanceof Array; }
        if (!isMatrixRaw(rows)) {
            // init rows with an array
            rows = new Array(rows).fill(0).map(_ => new Array(cols).fill(0));
            return new Matrix(rows);
        } else {
            this.rows = rows; // it's a number[][] now for sure
        }
    }
}

Возможно, вы решите реорганизовать свой код, чтобы этот дополнительный вызов не требовался.Просто сделайте проверку сначала, а затем сделайте большую часть работы вашего конструктора, как если бы вызов был сделан с number[][]

class Matrix {
    public rows: number[][];
    constructor(arr: number[][]);
    constructor(rows: number, cols: number);
    constructor(rows: number[][]|number = 0, cols: number = 0) {
        function isMatrixRaw(m: any): m is number[][] { return m instanceof Array; }
        if (!isMatrixRaw(rows)) {
            // init rows with an array
            rows = new Array(rows).fill(0).map(_ => new Array(cols).fill(0));
        }
        this.rows = rows; // it's a number[][] now for sure
    }
}
...