Вы могли бы использовать условный тип для представления типа кортежа остальных аргументов для конструктора:
export class ResponseDto<T extends Record<string, any> | Array<Record<string, any>>> {
public readonly sucess = true;
public paging: Paging | undefined;
constructor(
public data: T,
...[paging]: (T extends Array<any> ? [Paging] : [])
) {
this.paging = paging;
}
}
Выше paging
аргумент будет принят тогда и только тогда, когда тип T
является массивом. Внутри реализации класса свойство paging
установлено на Paging | undefined
. Может оказаться трудным, чтобы реализация класса знала, когда Paging
присутствует, а когда нет, так как компилятору сложно рассуждать об условных типах, которые зависят от неуказанных универсальных шаблонов.
Но, по крайней мере, со стороны вызывающего абонента это должно работать, как ожидалось:
declare const paging: Paging;
const okayObject = new ResponseDto({ a: "hello" });
const badObject = new ResponseDto({ a: "hello" }, paging); // error!
// expected 1 arg, got 2
const okayArray = new ResponseDto([1, 2, 3], paging);
const badarray = new ResponseDto([1, 2, 3]); // error!
// expected 2 args, got 1
Хорошо, надеюсь, это поможет; удачи!
Детская площадка ссылка на код