Okay, I will admit that is a bit of a contentious title. However, after this classic command line utility saved me hours of repetitive work I felt it needed to be said.

An Ideal Use Case

In the earlier days of TypeScript, string enums did not exist. There were, however, several different workarounds that accomplished a similar goal. The variant that my company used internally involved creating a class with a number of static getters that returned string values. For example,

export class BillingMethod {static get Cash() { return 'cash'; }static get Check() { return 'check'; }static get CreditCard() { return 'credit card'; }}

// Usage:const billingMethod = BillingMethod.Cash;

This method provides most of the benefits of a traditional enum, but it misses out on the enum’s biggest advantage: providing proper type support for the data structure. Each of the above getter functions returns a string, rather than a custom type.

When TypeScript 2.4 announced string enum support, it was obvious that a refactor was necessary to enable proper typing throughout our application. But how were we going to replace the hundreds of exported classes with their enum counterparts?

The answer, of course, is sed. With one simple script, we can turn the original, imitation enum into a real one:

sed \-i \-e 's/class/enum/' \-e 's/static get //' \-e 's/() { return/ =/' \-e 's/; }/,/' \./billing-method.ts

Outputs:

export enum BillingMethod {Cash = 'cash',Check = 'check',CreditCard = 'credit card',}

Apply the script over a folder of TypeScript files by changing the destination to ./constants/*.ts and we have successfully refactored every enum in our application.

Breaking It Down

Sed’s syntax looks impenetrable if we only pay it a quick glance. However, it only takes about fifteen minutes of experimentation to turn it into one of the most powerful refactoring tools.

Here’s a rundown of the keywords used in the above program:

Now let’s look at each of the expressions:

When sed’s syntax is broken down it is both simple and expressive. Although this is a straightforward use case, it can be applied to a wide variety of code refactorings.

I hope that this tool will save you as much time as it has for me.

Further Reading