September 25, 2020
Development

Tips for using TypeScript

7 min reading
Tips for using TypeScript

In this article, i'll share with you some Tips for using TypeScript. Most of the examples are demonstrated in the example of a React application.


Who is this article for?

  • developers, who want to learn new things about TypeScript
  • devs & teams, who implement/use TypeScript
  • all interested and not indifferent


What is TypeScript?

TypeScript (TS) is a superset of JavaScript (JS) syntax that is optionally typed and compiled (using TSC or Babel) to plain JavaScript. Technically, TS is statically typed JS.

“Adopting TypeScript is not a binary choice, you can start by annotating existing JavaScript with JSDoc, then switch a few files to be checked by TypeScript and over time prepare your codebase to convert completely.”

Once compiled, the program can be run in any modern browser or used on a server (Node.js or Deno).


Why is TypeScript?

  • Powerful type system, including generics, functions with optional parameters, functions with REST parameters, modules support and others
  • Typing is very important because it helps to get rid of many compile-time errors, such as: 'undefined' is not a function
  • Types are optional: with TypeScript, we can make a huge improvement over plain JavaScript. It is easier to refactor code without breaking it significantly.
  • TypeScript has excellent tooling, most modern code editors and IDLE support TS
  • TypeScript evolves with standards: the TS team contributes to the TC39 committees which help guide the evolution of the JavaScript language. For example the TS team championed proposals like Optional Chaining, Nullish coalescing Operator, Throw Expressions and RegExp Match Indices.
  • TypeScript makes code easier to read and understand
  • TypeScript has good documentation


Tips for using TypeScript

Always prefer to specify the types of variables, parameters, and return valuesto use the full power of TypeScript. This makes future refactoring easier. Most of the examples are demonstrated in the example of a React application.


Required minimum of TypeScript

         

Tip 1: intolerance for mistakes

  • Add type checking for dev mode.
  • Add type checking to CI for every pull request.
  • Optionally, you can add type checking on every commit.


      

There are two main ways to compile ts files: original TSC and @babel. The babel method is interesting in that information about types is stripped out from .ts files, due to which the assembly is fast.


Tip 2: use TypeScript aliases

Create prettier imports by defining paths and baseUrl properties to compilerOptions in tsconfig.json


This will avoid long relative paths when importing.

       


       

Tip 3: use any right

First opportunity. You can disallow the use of any using the --noImplicitAny key for the tsc compiler, or add the noImplicitAny property to compilerOptions in tsconfig.json.


Second possibility to use alias:

       

Why do we use any?

  • complex code, urgent task
  • efforts do not pay off

Sometimes it's better to use unknown instead of any

       

Tip 4: use never

never is a good insurance against unprocessed cases.

never in React: for example, you can prevent nesting or passing props:

       

Tip 5: types vs. interfaces

Use types when you need union or intersection. Use an interface whenever you want to use extends or implements. However, there is no hard and fast rule, use what works for you.


TypeScript 3.2 (Nov 2018)

     

Tip 6: do not use namespaces

Since we have ES6 modules as a standard in JavaScript, we don’t need custom TypeScript modules and namespaces. Instead, we should use standard JavaScript modules with import and export instead.


do not do this:

     

do this:

     

Tip 7: override types that don't suit you

When might you need it?

  • types are too general
  • types contain errors
  • the version of the types does not match the version of the used library
 

Typings are usually located in a separate directory typings/index.d.ts. You can connect them in tsconfig.json


Tip 8: use getters and setters

TypeScript supports the syntax of getters and setters. Using getters and setters to access object data is much better than accessing its properties directly.

Why?

  • If you want to implement more than just property access, you need to change the implementation in one place, not throughout the code
  • You can lazily load the properties of your object, for example, from the server
  • Easily add logging and error handling at the getter and setter level
  • Validation is easy to implement at the set implementation level
  • Encapsulating internal state
     

Tip 9: literal type vs enum

with enum:

     

with literal type:

     

both:

 

In this example, both components are checked for the color type. The enum version turned out to be more redundant - this is additional code during compilation, and additional imports in the source code. The string literal variant is more short and also contains type checking. There is no point in complicating the enum code.


  • Prefer string literals for simple type checking.
  • Use enum to describe more complex logic. 
  • It is better to give preference to const enum(however this structure is not supported by babel, you will have to add a plugin).


Criticism of enum 


If you need to support runtime enums use following pattern:

    

Tip 10: use const assertions

as const tells the compiler that the given object will not change. Hence, you can deduce the types in more detail.

    

You can also apply as const to arrays:

    

Tip 11: branded types

Brand is the small utility for creating unique ("branded") types. Usually such types are created on the basis of primitive ones - strings, numbers.

    

Tip 12: discriminated union

    

This creates a union of types with a common part. When working with such a union, the ts compiler can filter out variants and concretize the type.


Tip 13: use immutability

The type system in TypeScript allows you to mark individual properties of an interface/class as readonly fields. For more complex scenarios, there is a built-in type Readonly, which takes a type T and marks all of its read-only properties using mapped types (see mapped types).

    

Tip 14: use type for defining State or DefaultProps

    

Using freezing on initialState and defaultProps, the type system will infer the correct readonly types.

Why use type?

  • Using readonly and freezing, any change to the component will immediately result in a compile-time error
  • Type information inferred from implementation
  • Less boilerplate code describing types
  • Well readable code


Conclusion

Using TypeScript in a project changes the way we write code. It becomes easier to understand refactoring  the code. You do not need to keep in mind the implementation details.


With new advantages come new challenges - maintaining the correct type system.


I hope these tips will help you to improve your system. Of course, this is not a complete list, but it can serve as a good starting point.

Nick K
Author
Nick K
tags: development,dev

Keep reading

No blog posts

Build startups

With us

qusion
© Qusion 2022