首页 > 解决方案 > 可以通过接收到的构造函数参数动态地计算类属性吗?

问题描述

基本上我想要实现的是合并这两个分类:

类 ResponseDto

export class ResponseDto<T = Record<string, any>>  {
    public readonly sucess = true;

    constructor(
        public data: T
    ) { }
}

类 IterableResponseDto

export class IterableResponseDto<T = Record<string, any>[]> {
    public readonly sucess = true;

    constructor(
        public data: T,
        public paging: Paging
    ) { }
}

正如你所看到的,当data参数是一个数组时,你可以提供一个paging特定类型的参数,否则只能data是强制性的。

标签: typescripttypescript-typingstypescript-generics

解决方案


您可以使用条件类型来表示构造函数的其余参数元组的类型:

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

好的,希望有帮助;祝你好运!

Playground 代码链接


推荐阅读