Categories
TypeScript Best Practices

TypeScript Best Practices — Interfaces vs Type Aliases and Unnecessary Syntax

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.

Class Name Casing

TypeScript class names should be PascalCase.

This also applies to interfaces.

So we write:

class Foobar {}

and:

interface FooBar {}

Use UTF-8 Encoding for Files

We should use UTF-8 encoding for files.

This way, there won’t be any issues using the file anywhere.

File Name Casing

We should name our files with a consistent case.

We can stick with camel case, Pascal case, kebab case, or snake case.

Camel case is fileName.ts .

Pascal case is FileName.ts ,

Kebab case is file-name.ts .

Snake case is file_name.ts .

We just stick with one for all files.

Use Explicit Increment or Decrement Operators

We should use explicit increment or decrement operators to make sure that we just assign the new value and don’t use the return value.

For instance, instead of writing:

++i;
i++;
--j;
j--;

which return the value and do the increment or decrement operation, we write:

i += 1;
i -= 1;
j += 1;
j -= 1;

Interface

We may want to have interfaces that start with I to distinguish them from other entities.

For instance, we may want to write:

interface IFoo {
  bar: string;
}

Use Interface Over Type Literal

Interfaces can be implemented, extended, and merged, so they’re preferred to type literals.

For instance, instead of writing:

type Alias = {
  num: number
}

We write:

interface Foo {
  num: number;
}

Match Default Export Name

If we have a default export, then our default import should match the name of the export.

This reduces confusion.

So if we have:

bar.ts

export default foo;

Then we write:

import foo from bar;

Newline Per Chained Call

If we have a chain of method calls, then we may want to put each of them in a new line so that it won’t overflow the page.

For instance, instead of writing:

foo.bar().baz();

We write:

foo
  .bar()
  .baz();

No Angle Bracket Type Assertion

We should use as for type assertions since we can use it for type assertions in .tsx files in addition to .ts files.

So instead of writing:

const foo = <Bar>bar;

We write:

const foo = bar as Bar;

No Boolean Literal Comparison

We shouldn’t compare with boolean literals since they’re redundant.

For instance, we can shorten:

if (x === true)

to:

if (x)

Use of Parameter Properties

We can have parameter properties in the TypeScript code.

They let us pass in constructor parameter and assign it to a value at the same time.

Instead of writing:

class Animal {
  constructor(private numLegs: number) {}
}

We can write:

class Animal {
  private numLegs: number = 2;
  constructor(numLegs: number) {
    this.numLegs = numLegs;
  }
}

No Reference Import

We shouldn’t use reference if we use import .

For instance, if we have:

<reference path="foo.bar" />

We write:

import { bar } from 'foo';

It’s more standard and we don’t need reference to pull type definitions out of type definition files anymore.

No Useless Callback Wrappers

We shouldn’t have useless callback wrappers in our code.

For instance, instead of writing:

const handleContent = (content) => console.log('do something with', content);

promise.then((content) => handleContent(content))

We write:

const handleContent = (content) => console.log('do something with', content);

promise.then(handleContent)

It’s a lot cleaner.

No Unnecessary Initializers

We shouldn’t have to set variables to undefined .

For instance, instead of writing:

let x =  undefined;

We write:

let x;

No Object Literal Key Quotes

If an object literal has valid identifiers as property names, then we don’t need quotes around the names.

For instance, instead of writing:

const obj = { 'foo': 1 };

We write:

const obj = { foo: 1 };

Conclusion

We should have a consistent file name casing.

Also, we shouldn’t have unnecessary syntax in our code.

Imports should be used to pull data type definitions instead from external sources.

Useless callback wrappers should also be removed.

Interfaces should be used instead of type alias since they’re more versatile.

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 *