Typescript - First Steps

One of the things that makes JavaScript easier (comparatively) for an upcoming coder to pick it up easily is it’s dynamic typed approach (also known as ‘loosely typed’ approach) where a variable can be re-assigned to any other type without running into compiler errors. In other words, Types are not enforced in JavaScript (similar to Python to some extend) or there is no ‘Type-Safety’ in JavaScript.

But this very approach will introduce unintentional problems in the code flow especially in a growing code base. It can be difficult to understand what types of data are being passed around in JavaScript. Since type is not enforced, compiler turns a blind eye towards errors that might arise at runtime that are coming from types.

Before Typescript:

// loosely typed variables where type is not enforced
let x = 10;
x = 'Piyush'; // no error since javascript doesn't enforce type
x = true; // no error since javascript doesn't enforce type

This basic problem we have with type-safety is what TypeScript is trying to solve. TypeScript is a free and open-source high-level programming language developed by Microsoft that adds static typing (‘type-safety’) with optional type annotations to JavaScript. Type-safety in TypeScript helps to catch JavaScript runtime errors at compile time (or build time).

After Typescript:

let x: number = 20; // or simply let x = 20;
x = 'Piyush' // error - type 'string' is not assignable to type - 'number'

TypeScript is a ‘syntactic super set’ of JavaScript which adds static typing. This basically means that TypeScript adds syntax on top of JavaScript, allowing developers to add types. Therefore, it is a must that in order to learn TypeScript, one must know JavaScript.

Installing TypeScript

We cannot run a TypeScript code in a browser. TypeScript is meant for development purpose only.

sudo apt install node-typescript

To add it to NodeJS based projects, ‘nodejs’ and ‘npm’ must be installed before one can install TypeScript. Once the pre-requisites are installed, then we can install TypeScript using npm:

npm install typescript --save-dev

(‘-- save-dev’ because we deploy JavaScript code to production which is compiled from TypeScript)

A new file ‘tsconfig.json’ will be added to your project repository when this is done. To verify the installation of TypeScript, we can use the following command, and if it returns a version, then that confirms TypeScript is successfully installed.

tsc --version

Once done, then we can start writing TypeScript code in ‘.ts’ files.

Different ways to assign type to a variable

  1. First Declaration: Typescript will take a note of the type when it is first assigned and throws error later if re-assigned. This is not the preferred approach.
let x = 0;
let y = 'Piyush';
let z = true;
  1. Explicit Declaration: Alternatively we can explicitly declare the type of the variable by specifying it in this format - <variable-name> : <type>. This is the preferred approach.
let x: number = 0;
let y: string = 'Piyush';
let z: boolean = true;
  1. ‘any’ Type: this declaration allows the variable to be of any type. This is not a preferred type; use it only if you are sure what you are doing.
let x: any = 0; //
  1. Multiple Types: If the code demands a variable to be reassigned to a different type, we can mention the types that the variable is allowed to exist with a ‘|’ operator.
let x: number | boolean | string = 0;

TypeScript in Functions

Functional arguments can be type checked by explicitly mentioning them:

function addNumbers(x: number, y: number){
    return x + y;
}

if one of the arguments passed can be optional, we can mark it with ‘?’ and then mention it’s type.

function createUser(firstname: string, lastname?: string}){
    return "Hello " + firstname + (lastname || ''); 
}

TypeScript ensures optional arguments are properly handled by throwing errors when used as regular parameters.

function createUser(firstname: string, lastname?: string){
    const trimmedLastName = lastname.trim(); // error: 'lastname' is possibly undefined
}

we can handle such cases like this:

function createUser(firstname: string, lastname?: string){
    const trimmedLastName = lastname?.trim(); // optional argument handled
}

What if the variable that accepts the optional argument has a type? In such cases, we need to use ‘||’ and pass the default value of that type to ensure type-safety. See example below:

function createUser(firstname: string, lastname?: string){
    const trimmedLastName: string = lastname?.trim() || ""; // type-safety handled
}

TypeScript is happy as long as the types match.

NPM packages

NPM packages which are compatible with TypeScript are denoted with ‘TS’ (TypeScript) next to their name in the NPM website as seen below:

Those which aren’t are denoted with ‘DT’ (Type Definition) as seen in the screenshot below:

If we need to use NPM packages with ‘DT’ denotation in our TypeScript code base, then we need to install ‘@types/<package-name>‘ version of that package as dev dependency in addition to the regular package. Let’s take the example of ‘express’ package:

npm install express
npm install @types/express -D // since express is not a TS npm package and is a DT package

Note: make sure the version of the express is the same in both (use version for better results)

TypeScript to JavaScript

As stated before, TypeScript is used to ensure type-safety in JavaScript code. Once the TypeScript code file is completed, we can compile it to JavaScript by the TypeScript compiler using the command:

tsc hello.js // compiles and creates a new file 'hello.js' which is the JavaScript version of 'hello.ts' file

For one file this is fine. What about an entire TypeScript code-base?

In general, TypeScript developers place the source code inside the ‘src’ folder which the TypeScript compiler compiles and then place the compiled code inside a new folder - ‘dist’. They setup this in the ‘tsconfig.json’ and ‘package.json’ files.

First update the ‘tsconfig.json’ file:

// search for and update the following sections in the 'tsconfig.json' file:
"rootDir" : "./src" // where is the root directory
"outDir" : "./dist" // where the compiled code should be kept (DO NOT PUSH THIS FOLDER TO GIT)

Basically we are telling the TypeScript compiler that when compiling the code base, take the code inside the ‘src’ folder, compile it and place it inside ‘dist’ folder:

Then update the ‘package.json’ file:

"script" : {
    "build":"tsc -p .",
    "start":"node dist/index.js",
}

we have added to commands - build (find the root directory build it and place it in the dist folder, as configured inside the ‘tsconfig.json’ file) and start (find the index.js file inside the dist folder and run it)

Reference:

  1. Chaicode’s Web Dev Cohort by Hitesh Choudhary & Piyush Garg

  2. Learn TypeScript from W3Schools

0
Subscribe to my newsletter

Read articles from Mishal Alexander directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Mishal Alexander
Mishal Alexander