如何调整 class 以接收来自各种函数的不同参数?

How to adapt a class to receive different parameters from various functions?

我有一个 Typescript 项目,我正在其中创建一个 builder 来形成不同方法的所有对象。 我正在尝试为所有方法调整相同的构建器,以免使 类.

过程混乱

目前我有两个具有不同变量的函数,它们调用同一个构建器来创建每个对象,但由于变量不同,我不知道如何将它们传递给构造函数或如何告诉它哪些变量采取。

这是我当前的构建器class:

export interface Constants {
  sheetId: number,
  lastRow: number,
  totalHeader: number
}
export interface Req {
  requests: Array<object>
}

export class Builder {

  private dataInit: Req;
  private dataProp: Constants;

  constructor(sheetId: number, totalRow?: number, totalHeader?: number) {
    this.dataInit = {
        requests: []
    };
    this.dataProp = {
        sheetId: sheetId,
        lastRow: totalRow ? totalRow : 0,
        totalHeader: totalHeader ? totalHeader : 0
    };               
  }

  testOne() {
    this.dataInit.requests.push(
      {
        dataOne: {
          sheetId: this.dataProp.sheetId,
          endRow: this.dataProp.lastRow
        }
      }
    )
    return this.dataInit;
  }

  testTwo() {
    this.dataInit.requests.push(
      {
        dataTwo: {
          update: {
            sheetId: this.dataProp.sheetId
          },
          change: {
            header: this.dataProp.totalHeader
          }
        }
      }
    )
    return this.dataInit;
  }

}

这些是我的 functions:

function testOneData() {
  let sheet: number = 123;
  let rowTotal: number = 25;

  let dataObj = new Builder(sheet,rowTotal).testOne()

  console.log(JSON.stringify(dataObj))
}

function testTwoData() {
  let sheet: number = 123;
  let headerTotal: number = 2;

  let dataObj = new Builder(sheet,headerTotal).testTwo()

  console.log(JSON.stringify(dataObj))
}

testOneData()

我的问题:现在第一个功能有效,但第二个功能 returns 0header 键中。我如何为这两个功能调整构建器或使其通用以实现更多功能?我怎么能从构建器那里知道哪些变量会传给我?

如果我的理解没错,那么您想将参数作为单个对象而不是列表传递。

例如:

  constructor({
    sheetId,
    totalRow = 0,
    totalHeader = 0
  }: {
    sheetId: number,
    totalRow?: number,
    totalHeader?: number
  }) {
    this.dataInit = {
        requests: []
    };
    this.dataProp = {
        sheetId,
        lastRow: totalRow,
        totalHeader,
    };               
  }

现在 totalRowtotalHeader 由传入对象上 属性 的名称引用,而不是参数列表中的位置。这意味着您可以按任何顺序传递它们,并可以毫无问题地忽略任何可选的。

然后你像这样调用这个构造函数:

let dataObj = new Builder({sheetId: sheet, totalRow: rowTotal}).testOne()

  let dataObj = new Builder({sheetId: sheet, totalHeader: headerTotal}).testTwo()

然后你得到正确的结果:

testOneData() // "{"requests":[{"dataOne":{"sheetId":123,"endRow":25}}]}" 
testTwoData() // "{"requests":[{"dataTwo":{"update":{"sheetId":123},"change":{"header":2}}}]}"

有关工作示例,请参阅 this Typescript Playground。只需按左上角的“运行”按钮即可亲自查看控制台输出。


请注意,如果您这样做:

new Builder(dataRequiredForTestOne).testTwo() // fine

那么这将被允许,它只会使用那些默认的零。如果这对您的用例来说是个问题,那么这个答案会变得更加复杂,并且需要打字稿通用参数,这可能在另一个问题中得到最好的回答。