Categories
TypeScript Best Practices

TypeScript Best Practices — Comparisons, Useless Types, and any

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 disallowing the use of useless comparisons.

Also, we don’t want to write conditionals for things that are always truthy or falsy.

Useless namespace or enum qualifiers can also be removed.

And we should add type annotations to functions before calling them.

Don’t do Equality Comparison Against Boolean Literals

We shouldn’t do equality comparisons against boolean literals.

We can omit it and get the same result.

For instance. the following:

if (someCondition === true) {
}

is the same as :

if (someCondition) {
}

and:

if (someCondition === false) {
}

is the same as:

if (!someCondition) {
}

So we shouldn’t compare against boolean literals.

Don’t Write Conditionals that are Always Truthy or Falsy

We shouldn’t write conditionals that are always truthy or falsy.

For instance, we shouldn’t have code like:

const foo = (arg: 'baz' | 'bar') => {
  if (arg) {
  }
}

because arg is either 'bar' or 'baz' , so it’s always truthy.

In addition to if , this also applies to for , while and do-while statements and base values of optional chaining expressions.

For instance, if we have:

const foo = (arg: string) => {
  return arg?.length;
}

Since arg can never be bullish, so we don’t need the ? .

No Useless Namespace Qualifiers

We shouldn’ write useless namespace or enum qualifiers.

For instance, instead of writing:

namespace A {
  export type B = number;
  const x: A.B = 3;
}

We write:

namespace A {
  export type B = number;
  const x: B = 3;
}

since B is in A , we don’t need to specify A .

Likewise, for enums, instead of writing:

enum A {
  B,
  C = A.B,
}

We write:

enum A {
  B,
  C = B,
}

Again, B is in A , so we don’t have to write A .

Remove Type Arguments that aren’t Used

We may want to remove explicit type arguments that are the same as the default.

This is because they’re redundant.

For instance, instead of writing:

function foo<T = number>() {}
foo<number>();

We just write:

function foo<T = number>() {}
foo();

Likewise, for function signatures, instead of writing:

class C<T = number> {}
function bar(c: C<number>) {}

We can write:

class C<T = number> {}
function bar(c: C) {}

Don’t Write Useless Type Assertions

If a type assertion doesn’t change the type of an expression, then we shouldn’t write it.

For instance, instead of writing:

const foo = 5;
const bar = foo!;

or:

const foo = <3>3;

or:

const foo = <3>3;

We should write:

const foo = <number>3;

or:

const foo = 3 as number;

or:

const foo = 3 as const;

Changing 3 to the literal type 3 doesn’t change the type.

But changing 3 to the type number does change the type by making it broader.

Don’t Assign any to Variables and Properties

We shouldn’t change the type of any value to any or any[] .

They bypass TypeScript type checks so makes our TypeScript code less robust.

Therefore, instead of writing:

const x = 1 as any;

or:

const [x] = [1] as any[];

We write:

const x = 1 as number;

or:

const [x] = [1] as number[];

Don’t Call any Type Value

We may also look out for any properties or other nested locations.

For instance, instead of writing:

declare const nestedAny: { prop: any };
nestedAny.prop.a();

We may write:

declare const nestedAny: { prop: : { a: () => void } };

Now we can call:

nestedAny.prop.a();

safely since we know nestedAny.prop.a must be a function.

Conclusion

Writing conditionals for things that are always truthy or falsy are redundant, so we should remove it.

Also, useless type assertions that don’t change the type of value should be removed or changed.

Comparing against boolean literals are also redundant so we should also remove those.

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 *