Nodejs server using Typescript

Understand Typings in Typescript

There are two main ways you can publish your type declaration files of an npm package to npm:

  1. bundling with your npm package, or
  2. publishing to the @types organization on npm.

If your package is written in TypeScript then the first approach is favored. Use the --declaration flag to generate declaration files. This way, your declarations and JavaScript will always be in sync.

If your package is not written in TypeScript then the second is the preferred approach.

If your package has a main .js file, you will need to indicate the main declaration file in your package.json file as well. Set the types property to point to your bundled declaration file. For example:

For ex: uuid npm package:
Solution: import * as uuid from ‘uuid’;

An easy way to run Typescript files

npm install — save-dev ts-node //Only for development, not to be used in prod
With ts-node installed, let's add a npm script task to run our test program above, which will be in a file called test.ts:
“scripts”: { “demo”: “./node_modules/.bin/ts-node ./test.ts” },

Now do, npm run demo

With Typescript, we can mostly have both the convenience of plain Javascript plus the enhanced tooling. If we use libraries that provide their own built-in types, we can have auto-completion, refactoring and find usages almost everywhere in our program, at the expense of using just a few type annotations at strategic places.

The biggest exception for this will be function parameters, where there is no way for the compiler to infer what is the type of a function parameter. But it’s a great idea to mention the types of our function parameters for documentation purposes.

How to make the most of Typescript type definitions

If you want to leverage Typescript type inference to its maximum and have it auto-detect the type of the largest amount possible of variables, the best way is to go to the tsconfig.json and set the noImplicitAny property to true:

{ “compilerOptions”: { “module”: “commonjs”, “target”: “es5”, “noImplicitAny”: true, “sourceMap”: false }}

For some reason, if the compiler can’t infer the type of a variable, it will not implicitly assign it the type any. This is probably one of the most important properties available to configure the compiler.

What is @types/node module?

The Node runtime does not ship with its own type definitions, so we need to import those types separately. Where can we find them? They are also in npm but need to be installed separately.

We can install the node runtime type definitions in the following way:
npm install @types/node — save-dev
This @types/nodepackage is where we can find a ton of useful type definitions, such as for example the type definitions of node that allow us to use require for example.

The @types scope package contains type definitions for a lot of libraries, like Express, Sequelize, JQuery, and many others. So definitively have a look there if you are missing some type definitions, but make sure of two things first:

  • check if the package you are using already has types built-in, and if so prefer those
  • check if type definitions are already shipped with the compiler, more on this later

Handling the gap between libraries and the compiler

The Typescript compiler will apply the latest type checks to any type definitions available in node modules, including @types.

To avoid this, and ensure that only our program is checked by the compiler we can use the flag skipLibCheck to true.

It’s a great idea to use the compiler built-in types (the lib flag) as much as possible because those types are written to maximize the type safety of our programs and make sure we conform to standard APIs.

When should we use @types ?

It’s better to instead of using @types systematically, to try to use the built-in types of each module as much as possible, and use @types strategically if necessary for example for modules like Express or Sequelize.

Plain Javascript modules like those two will likely make the bulk of your program and have great types available on @types. But for example newer modules like Firebase: they already come with types now.

So if you also install @types/firebase you will run into duplicate type issues.

On the other hand things like @types/node are essential to writing any node program.

So the suggestion here is: have a look at the built-in types to see if there is anything there similar to what you are looking for. Have a look at the node module itself to see if it has already types inside it: this will be more and more common.

If no types are found neither inside the module nor built-in to the compiler, then have a look at @typesto see if there are some good types there. Fast forwarding to the future, the ideal would be that @types no longer exists and that most libraries ship their own type definitions.

Suffering from Knowledge Quest

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store