Home > OS >  Typescript / Javascript - How to avoid duplicated code
Typescript / Javascript - How to avoid duplicated code

Time:12-19

I have a piece of code that basically repeats itself. The only difference is the type of params and scan invokes this.getDbClient().scan(params) and query invokes this.getDbClient().query(params)

static scanTable = async (params: DynamoDB.DocumentClient.ScanInput) => {
    let items;
    let scanResults: any[] = [];
    do {
        items = await this.getDbClient().scan(params).promise();
        (items.Items || []).forEach((item) => scanResults.push(item));
        params.ExclusiveStartKey = items.LastEvaluatedKey;
    } while (typeof items.LastEvaluatedKey !== 'undefined');

    return scanResults;
}

static queryTable = async (params: DynamoDB.DocumentClient.QueryInput) => {
    let items;
    let scanResults: any[] = [];
    do {
        items = await this.getDbClient().query(params).promise();
        (items.Items || []).forEach((item) => scanResults.push(item));
        params.ExclusiveStartKey = items.LastEvaluatedKey;
    } while (typeof items.LastEvaluatedKey !== 'undefined');

    return scanResults;
}

I tried to extract the function and use

async (params: DynamoDB.DocumentClient.ScanInput | DynamoDB.DocumentClient.QueryInput)

and then trying to do instanceof DynamoDB.DocumentClient.ScanInput and instaceof DynamoDB.DocumentClient.QueryInput but it seems that instanceof cannot be used:

ERROR: Property 'ScanInput' does not exist on type 'typeof DocumentClient'.ts(2339)

ERROR: Property 'QueryInput' does not exist on type 'typeof DocumentClient'.ts(2339)

What can I do here to avoid duplications?

CodePudding user response:

oh the problem is quite simple you can write it like this:

static scanTable = async <T extends "scan" | "query", P extends T extends "scan" ? DynamoDB.DocumentClient.ScanInput : DynamoDB.DocumentClient.QueryInput>(type: T, params: P) => {
    let items;
    let scanResults: any[] = [];
    do {
        items = await this.getDbClient()[type](params).promise();
        (items.Items || []).forEach((item) => scanResults.push(item));
        params.ExclusiveStartKey = items.LastEvaluatedKey;
    } while (typeof items.LastEvaluatedKey !== 'undefined');

    return scanResults;
}

then use it like this

scanTable("scan", <param for scan>)
scanTable("query", <param for query>)

CodePudding user response:

here is what you can do :

class Table {
  static getTable = async (inputType: 'ScanInput' | 'QueryInput',searchType : 'scan' | 'query') => {
    let documentClient = DynamoDB.DocumentClient[inputType]
    let items;
    let scanResults: any[] = [];
    do {
      items = await this.getDbClient()[searchType](params).promise();
      (items.Items || []).forEach((item) => scanResults.push(item));
      params.ExclusiveStartKey = items.LastEvaluatedKey;
    } while (typeof items.LastEvaluatedKey !== 'undefined');

    return scanResults;
  }
}

and use it in this way :

Table.getTable('ScanInput','scan')
Table.getTable('QueryInput','query')
  • Related