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')