Categories
TypeScript Best Practices

TypeScript Best Practices — Function and Array Types, Reducing Complexity

Spread the love

To make code easy to read and maintain, we should follow some best practices.

In this article, we’ll look at some best practices we should follow to make everyone’s lives easier.

Use isNaN to Check for NaN

NaN doesn’t equal itself, so we can’t use === or !== to check for NaN .

Instead, we use the isNaN function to check for it.

So instead of writing:

if (foo === NaN) {}

We write:

if (isNaN(foo)) {}

Invalid Use of void

We should watch for invalid uses of void .

We shouldn’t mix void with other types since void means nothing rather than an explicit type of value.

If we need undefined , then we should use the undefined type.

So types expressions like:

Foo | void

should be replaced with:

Foo | undefined

Max Number of Classes Per File

We shouldn’t have too many classes per file.

It’s probably too complex if we do.

We can set the max number of classes per file with a linter.

Max File Line Count

If a file has too many lines, then it’s probably too complex and hard to read.

We can set the max file line count in a file with a linter.

Default Exports

Default exports aren’t as clear, so we should avoid using them.

Named exports are clearer.

So we may want to avoid them.

Default Import

Like default exports, default imports aren’t as clear as named imports.

No Duplicate Imports

We can combine multiple import statements from the same module into one import statement, so we should do that.

For instance, instead of writing:

import { foo } from 'module';
import { bar } from 'module';

We write:

import { foo, bar } from 'module';

No Mergeable Namespace

We shouldn’t have 2 namespaces with the same name so we don’t have to think about how they’ll be merged together.

Instead, we can just name different namespaces with different names.

For instance, instead of writing:

namespace Animals {
  export class Dog {}
}

namespace Animals {
  export interface Cat {
    numberOfLegs: number;
  }
  export class Zebra {}
}

We write:

namespace Pets {
  export class Dog {}
  export interface Cat {
    numberOfLegs: number;
  }
}

name WildAnimals {
  export class Zebra {}
}

No require Imports

Now that ES modules are widely available, we can replace require with import .

For instance, instead of writing:

const { bar } = require('foo');

We can use the ES6 module version of the module and write:

import { bar } from 'foo';

Use const

We should use const instead of let or var whenever we can for declaring variables.

This way, they can’t be accidentally be assigned with another value.

For instance, instead of writing:

var x = 1;
let y = 2;

We write:

const z = 3;

Marking Variables as readonly

We should mark variables as readonly if they’re private and are never modified outside of the constructor.

This way, we won’t be able to accidentally change them.

For instance, instead of writing:

class Foo {
  private bar = 1;
}

We write:

class Foo {
  private readonly bar = 1;
}

Arrow return Shorthand

If we have an arrow function that only has one statement and returns something, we can make them shorter.

Instead of writing:

() => { return x; }

We write:

() => x

Set Array Types

We should set the types of the array content so that we can restrict the types of values that go into the array.

We can also set generic types to make the array generic.

For instance, instead of writing:

const arr = ['foo', 'bar', 1];

We write:

const arr: string[] = ['foo', 'bar', 'baz'];

Callable Types

If we have an interface or a literal type with just a call signature, then we should write it as a function type.

For instance, instead of writing:

interface SearchFunc {
  (source: string, subString: string): boolean;
}

We write:

(source: string, subString: string) => boolean

Conclusion

We should use function types instead of interfaces or literal types with just a function signature.

Arrays should have a type so we can’t put any type of data in it.

We should reduce the complexity of each file.

isNaN should be used for checking for NaN .

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 *