Categories
TypeScript Best Practices

TypeScript Best Practices — Strings and Regex

Spread the love

TypeScript is an easy to learn extension of JavaScript. It’s easy to write programs that run and does something. However, it’s hard to account for all the uses cases and write robust TypeScript code.

In this article, we’ll look at the best practices to following when writing code with TypeScript, including using includes over indexOf .

Also, we look at why we should use Regex.exec instead of String.match and why we should use the namespace keyword instead of using the module keyword to declare TypeScript modules.

Using includes Over indexOf

We should use includes over indexOf . It’s shorter and does the same thing.

There’s an includes method for both strings and arrays.

For instance, instead of writing:

const arr = [1, 2, 3];
const hasOne = arr.indexOf(1) !== -1;

or:

const str =  'foobar';
const hasFoo = str.indexOf(1) !== -1;

We write:

const arr = [1, 2, 3];
const hasOne = arr.includes(1);

or:

const str =  'foobar'
const hasFoo = str.includes(1);

includes finds check if an instance of something exists in a string or an array and returns true if it exists and false otherwise.

Require the use of the namespace Keyword Instead of module to Declare TypeScript Modules

To prevent any confusion with ES6 modules, we should use the namespace keyword to declare TypeScript modules.

For instance, instead of writing:

`module` Shapes {
  export class Circle { /* ... */ }
  export class Square { /* ... */ }
}

we write:

export namespace Shapes {
  export class Circle { /* ... */ }
  export class Square { /* ... */ }
}

Use Nullish Coalescing Operator Instead of Logical Chaining

Now that TypeScript has the nullish coaslescing operator, we should use that instead of logical chaining.

For instance, instead of writing:

function func(foo: string | null) {
  return foo || 'hello';
}

We should write:

function func(foo: string | null) {
  return foo ?? 'hello';
}

?? is better since it returns 'hello' only if foo is null or undefined .

Use Concise Optional Chain Expressions Instead of Chained Logical And

Optional chaining expressions are better than a long chain of logical && ‘s.

Therefore, we should use that instead of AND expressions.

For instance, instead of writing:

function bar(foo: T | null) {
  return foo && foo.a && foo.a.b && foo.a.b.c;
}

We write:

function bar(foo: T | null) {
  return foo?.a?.b?.c;
}

As we can see, it’s much shorter and they do the same thing.

Private Members Should be Marked as readonly if they’re Never Modified Outside of a Constructor

We should mark private members of a class as readonly if they’re never been changed outside of a constructor.

This way, we can prevent them from being changed accidentally anywhere else.

For instance, instead of writing:

class Foo {
  private foo: string;
  public constructor() {
    this.foo = "bar";
  }
}

We write:

class Foo {
  private readonly foo: string;
  public constructor() {
    this.foo = "bar";
  }
}

Now we can’t change this.foo anywhere in the class.

Use Type Parameter When Calling array.reduce Instead of Casting

If we use array.reduce with generic types, like an array or object, then we should specify a type parameter so we can specify a useful type for the initial value.

We can do that with a type parameter instead of a type assertion.

For instance, instead of writing:

[1, 2, 3].reduce((acc, num) => acc + num, 0 as number);

We write:

[1, 2, 3].reduce<number>((acc, num) => acc + num, 0);

Now we enforce the type on everything instead of just the second argument.

Use Regex.exec Instead of String.match if no Global Flag is Provided

Regex.exec is after than String.match and they both work the same if the /g flag isn’t added.

For instance, instead of writing:

'foobar'.match(/bar/);

We write:

/bar/.exec('foobar');

However, if we want to get all results of a pattern, then we’ve to use String.match :

'555-1212'.match(/d+/g);

Conclusion

We should use includes instead of indexOf to check if something is in a string or array.

Also, we should use Regex.exec as much as possible instead of String.match for finding single matches.

To declare a TypeScript module, use the namespace keyword instead of module .

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *