Question:
How to handle more than 100 cases neatly on Typescript?

Handling more than 100 cases in a TypeScript switch statement might lead to code that is hard to read and maintain. If you have a large number of cases, consider alternative approaches to improve code organization and readability. 


Assuming the values in EnumBatchType can be meaningfully converted to strings, you could consider dynamically importing the batch class. Then you don't have a massive list of these anywhere except the file system, and changes you make to the code in any one batch are identified in source control as relating only to that batch, not others defined in the same source file (since each batch is in its file).


  1. Here's how you can do that:


export interface Batchable{

    doBatch():Promise<void>; // every batch class has this function

}

------ InputBatch, OutputBatch, RefineBatch, and so on...

export abstract class InputBatch<T> implements Batchable {

  abstract getDataFromKurve(): Promise<T[]>


  abstract getBodyFromData(datas: T[]): Promise<NexusTagDto>


  abstract updateNexusTag(body: NexusTagDto): Promise<NexusResponseDto>


  async doBatch(): Promise<void> {

    const datas = await this.getDataFromKurve()

    const body = await this.getBodyFromData(datas)

    const res = await this.updateNexusTag(body)

    unifiedLog('batch-finish', JSON.stringify(res), true)

  }

}

------

export default class Batch1 extends InputBatch<Something> {/*...*/}


...and similarly, batches/BatchType2.ts:



export default class Batch2 extends InputBatch<Something> {/*...*/}

...and so on. (For me, this is one of the very few acceptable uses of default exports.)

Then, getting the right batch class to use is roughly:

export async function batchStart() {

    const batchType = process.env.BATCH_TYPE;

    unifiedLog('batch_start', process.env.TARGET_SCHEMA);

    const client = await getBatchClient(batchType as EnumBatchType);

    //             ^−−− note

  

    if (client) {

        await client.doBatch();

        process.exit(0);

    }

}


// ...


async function getBatchClient(batchType: EnumBatchType): Promise<Batchable> {

    const BatchClass = (await import(`./batches/${batchType}.ts`)).default as new () => Batchable;

    const client = new BatchClass();

    return client;

}

Or if you want it to return null as it current does when there's no matching batch class, you could have getBatchClient handle the import error if the batch class didn't exist:

async function getBatchClient(batchType: EnumBatchType): Promise<Batchable> {

    let importError = true;

    try {

        const BatchClass = (await import(`./batches/${batchType}.ts`)).default as new () => Batchable;

        importError = false;

        const client = new BatchClass();

        return client;

    } catch (error) {

        if (importError) {

            return null; // Like your current code does

        }

        throw error;

    }

}

In both cases, this does have the concern that if the default export of one of these files is not a valid constructor for Batchable, the code will be incorrect in a way TypeScript can't detect for you, but it offloads the need for massive lists to the file system.


Suggested blogs:

>Why Typescript does not allow a union type in an array?

>Narrow SomeType vs SomeType[]

>Create a function that convert a dynamic Json to a formula in Typescript

>How to destroy a custom object within the use Effect hook in TypeScript?

>How to type the values of an object into a spreadsheet in TypeScript?

>Type key of record in a self-referential manner in TypeScript?

>How to get the last cell with data for a given column in TypeScript?

>Ignore requests by interceptors based on request content in TypeScript?

>Create data with Typescript Sequelize model without passing in an id?

>How to delete duplicate names from Array in Typescript?


Nisha Patel

Nisha Patel

Submit
0 Answers