Learning TypeScript Part 5- Functions

Functions

Just as in JavaScript functions can be created both as a named function or as an anonymous function. Similar to JavaScript TypeScript also captures variables.

function add(x, y) {
	return x + y;
}

let myAdd = function (x, y) { return x + y };

/**Typing the function */
function add(x: number, y: number): number {
	return x + y;
}

let myAdd = function (x: number, y: number): number { return x + y };

Contextual Typing

As you can see in the above example TypeScript compiler can figure out the type if you have types on one side of the equation but not the other.
This is called contextual typing a form of inference.

Optional Parameters

In JavaScript every parameter is optional but in TypeScript every parameter is required by default.
The number of arguments given in the parameters must match no.of arguments passed

Default Parameters

Even though TypeScript expects exact parameter list we can still be able to have optional parameters using the symbol ? But one catch is that all the optional parameters has to come in the end

function build(firstName: string, lastName?: string) {
	return firstname + ' ' + lastName;
}

build('Bob'); //Ok
build('a', 'b', 'c'); //too many params
  • Optional parameters used as a default value if a parameter is not provided with a value
  • Optional parameters not necessarily should be placed at the end of the params list
  • Default parameters that comes after all required params are treated as optional
function buildName(firstName: string, lastName = "Smith") {
	return firstName + ' ' + lastName;
}

buildName('Bob'); //returns Bob Smith
buildName('Bob', 'Ryan') // returns Bob Ryan

Rest params

Allows to pass any number of params

function restParamDemo(firstName: string, ...restOfName: string[]) {
	return firstName + ' ' + restOfName.join(' ');
}

restParamDemo('Bob'); //Valid
restParamDemo('Bob', 'Some 2'); //Valid
restParamDemo('Bob', 'Some 2', 'Some 3'); //Valid
//would be valid for any number of params

Lamdas

When using JavaScript you should be carefull while using ‘this’ keyword in callback. Lamdas can be used to capture this when function is created rather than when it is invoked

Overloads

  • JavaScript is inherently very dynamic language. A function can return any type of objects from string, number etc to complex objects based on the input
  • But this will not allow us to describe a type of the function effectively
  • Overloads allows us to use multiple function types for the same function as a list of overloads

Learning TypeScript Part 4 – Classes

Classes

Traditional JavaScript uses prototype based inheritance as the basic means of building up reusable components. but this is bit different from the object oriented approach to which we are most accustomed where classes inherit functionality and objects built from these classes. Starting ES6 JavaScript programmers will be able to build their applications using this object oriented approach.

Simple Class

class Vehicle {
	name: string;
	constructor(name: string) {
		this.name = name;
	}
	drive(distance) {
		console.log(`${this.name} moved ${distance} meters.`);
	}
}

let veh = new Vehicle('My Vehicle');

If you are a C# or Java programmer the syntax should look familiar to you. The keyword class is used to define a class

Inheritance

In TypeScript we can use common object oriented patterns. One of the fundamental pattern in object oriented programming is inheritance.

Let us see how we can do inheritence with below example.

class Bike extends Vehicle {
	constructor(name: string) {
		super(name);
	}

	drive(distance) {
		console.log('moving in two wheels');
		super.drive(distance);
	}
}

class Car extends Vehicle {
	constructor(name: string) {
		super(name);
		}
	drive(distance) {
		console.log('moving in four wheel');
		super.drive(distance);
	}
}

let hondo = new Bike('hondo');
let car: Vehicle = new Car('Tesla');

extends keyword is used to create a subclass

Car and Bike are the subclass the base class in Vehicle and the sub classes are able to access the base class features

Modifiers

TypeScript has three modifiers public, private and protected

  • public is default
  • private cannot be accessed from outside of the class
  • protected modifier acts much like private with the exception that memebers declared. protected can also be accessed by instances of deriving class

Parameter Properties

Parameter properties lets you to create and initialize a member in one place

Below is updated class definition of Vehicle using parameter properties

class Vehicle {
	constructor(private name: string) { }
	drive(distance) {
		console.log(`${this.name} moved ${distance} meters.`);
	}
}

Accessors

TypeScript supports getter and setter as a way of intercepting access to a member of an object. This gives you a way of having finer control over how a member is accessed on each object.

For example lets consider the below class

class Employee {
	fullName: string;

}

let employee = new Employee();
employee.fullName = 'Bob Smith';
if (employee.fullName) {
	console.log(employee.fullName);
}

While allowing people randomly set fullname directly is pretty handy, this might get us in trouble if people can change names on a whim

class Employee {
	private _fullName: string;

	get fullName(): string {
		return this._fullName;
	}

	set fullName(newName: string) {
		this._fullName = newName;
	}
}

Static Properties

Static members are the members that are visible on the class itself rather than than on the instances.

class Grid {
	static origin = { x: 0, y: 0 };
	constructor(parameters) {

	}
}
console.log(Grid.origin.x);
console.log(Grid.origin.y);

Abstract Classes

Abstract classes are base classes from which other classes may be derived. but they may not be instantiated directly. Unlike an interface abstract class may contain implementation details for its members

abstract keyword is used to define Abstract Classes and abstract methods

Methods within abstract classes must be implemented by derived class

abstract class Animal {
	abstract makeSound(): void;
	move(): void {
		console.log('roaming the earth');
	}
}

Learning TypeScript Part 3 – Interfaces

Interfaces

Interfaces are the most flexible way of describing types in TypeScript language. The only job of an interface in TypeScript is to describe a type. While classes and functions will deal with implementation.

To define an interface use the keyword interface.

interface IMovie {
 play(name: string): void;
}

Roles of Interfaces

  • Describing an Object
  • Describing an Indexable Object
  • Ensuring Class instance Shape

Describing an Object

In Javascript methods like $.ajax takes many arguments, but not necessarily we need to pass all the arguments whenever we use this method. TypeScript support this notion of optional properties to help you use these objects correctly.

interface IMovieSettings {
 name: string;
 length?: number;
 genre?: string;
}

function playMovie(movie: IMovieSettings) {
 ...
}

If ? symbol is used after some of the member names then it means that the member is optional.

playMovie({ name: 'The Hobbit' }); //OK
playMovie({ name: 'The Hobbit', length: '70 mins' }); // Invalid type for length
playMovie({ length: 70, genre: 'Adventure' }); // Property name is missing

Describing an Indexable Object

Indexable types have an index signature that describes the types we can use to index in to the object, along with corresponding return types when indexing

interface IMovies {
 [index: number]: string;
}
let movies: IMovies;
movies = ["The Hobbit", "Lord of the Rings", "Deadpool"];

Ensuring Class Instance Shape

Let’s extend the IMovies example above

interface IMovie {
 play(name: string): void;
 language: string;
}

we can implement this inrface  in a class using implements keyword

class HollywoodMovie implements IMovie {
language = 'English';

play(name: string) {
console.log(name);
}
}

Now we can use an instance of Hollywoodmovie wherever a IMovie is expected.

var movie: IMovie = new HollywoodMovie();

Similarly we can also use structural typing of TypeScript to implement the IMovie object literal.

var movie = {
play: (name: string) => { console.log(name) },
language: 'Any',
}

Learning TypeScript Part 2 -Variables

let and const are two new keywords introduced in the ECMAScript 6 (ES6, a.k.a. ES 2015) . Since TypeScript is the superscript of JavaScript the uses of let and const are already accessible in the language.

let is similar to var but it helps to avoid some of the common problems with var

const is similar to let plus is prevents the re-assignment of any variables.

var conundrum

var in JavaScript has some odd scoping rules when compared to other languages. var declarations are accessible within their containing function, module, namespace or global scope regardless of the containing block.

In other words JavaScript doesn’t have the concept of block scoping.


function callvalue(init) {
 if (init) {
 var x = 10;
 return x;
 }
 return x;
}

callvalue(true); //returns 10

callvalue(false); //returns undefined

Other quirks with vars

Allows multiple declarations of the same variable in same scope

Variable Capturing :  JavaScript always captures variables, not values

let

As we pointed our in the above section var have some problems which is why we should use let.

 let x = 10; 

As you can see let are declared in the same way as var’s, but the difference is not in the syntax but in semantics.

Block Scoping

Unlike var’s let uses block scoping or lexical scoping. For example the below code sample will throw error

function callvalue(init) {
 if (init) {
 var x = 10;
 return x;
 }
 // Error x doesnt exist here
 return x;
}

Note: You can use variables before its declared in TypeScript but the catch is that it is illegal to use variables before declaring in TypeScript. If we are targetting ES6 compatible runtime this will throw a run time error.

let x = 10;
let x = 20; // error: can't re-declare 'x' in the same scope

var allows for re-declaration of variables TypeScript wont

function some() {
 let x = 100;
 var x = 100; // error: can't have both declarations of 'x'
}

const

const declarations are similar to let but their value cannot be changed once its declared but all the scope rules that applies to let applies const too.

One catch to const though is its not immutable, its mutable. i.e you can’t reassign them but you can change the values.


const obj = {
 name: "Uma"
};

// left hand side cannot be a constant
obj = {
 name: "Mahes"
}

// valid assignment
obj.name = "Mahes";

Destructuring

The destructuring assignment statement is used to extract data from arrays or objects into distinct variables.

Array Destructuring

let fullname = ["Umamaheswaran","Manivannan"];

let [firstname, lastname] = fullname;

console.log(firstname); // outputs Umamaheswaran

console.log(lastname); // outputs Manivannan

 

Object Destructuring

let fullname = {
 firstname: "Uma",
 middlename: "M",
 lastname: "Mani"
}

let {firstname, lastname} = fullname;

Property renaming

let {firstname: givenname, lastname: surname} = fullname;

the above line is equal to

let givenname = fullname.firstname;
let surname = fullname.lastname;

Default Values

This feature allows us to assign a default value if a value is undefined

function myfunction(input: { a: string, b?: number }) {
 let {a, b = 100} = input;
}

In the above function in the input parameter v is declared as optional. If there are no values passed to b let keyword assigns them a default value of 100.

Function declarations

Destructuring also works for functions

function f({a, b} = {a: "", b: 0}): void {
// ...
}
f();

 

Conclusion

In the blog we have seen about variable declarations and its related features in the next blog we will look into interfaces and classes

Learning TypeScript Part 1 – Getting Started

Introduction

Typescript is a open sourced programming language developed by Microsoft. It is a Superset of Javascript and it compiles down to plain Javascript.

Typescript offers support for the latest and evolving Javascript features including ECMAScript2015 and future proposals like async.

Why Typescript?

Typescript provides a way to add optional static typing to our Javascript code.

It makes is possible to use future Javascript editions in the current Javascript engines.

Why typing?

Before going into typings we should remember that types are completely optional in Typescript.

One of the main advantage of statically typed languages are they provide great tooling during development process like static checking, compile time errors, code refactoring.

Types can enhance code quality and understandability.

All Javascript are Typescript!!

Typescript provides compile time type checking for your javascript code. but it does so in a less intrusive way. Since types are optional even though if there are any error related to types in your code Typescript will go ahead and generate the equivalent JavaScript code irrespective of the typing errors.

So to get started with typescript all you need to do is rename all your .js file to .ts file

Getting Started

Lets get started by installing the node package by using command below

>npm install typescript -g

Note: If you are Visual Studio 2015 and Visual Studio 2013 update 2 typescript works by default otherwise you can install it from Extensions

You can pick the editor of your choice, but I’m choosing Visual Code editor since it is Open Source and offers great support for typescript.

Inside your project directory create a file called helloworld.ts and include the below content.

function greet(name: string) {
return "Hello, " + name;
}

var greeter = greet("World");

Create a tsconfig.json file in the root directory

{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"sourceMap": true
}
}

The presence of tsconfig.json file indicates typescript that the directory is the root of a TypeScript project

Now lets add task.json file to make the editor build typescript files automatically

Create a task.json file under .vscode directory

{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "0.1.0",
"command": "tsc",
"isShellCommand": true,
"args": ["-w", "-p", "."],
"showOutput": "silent",
"isWatching": true,
"problemMatcher": "$tsc-watch"
}

now if you press Ctrl+Shift+B the editor will automatically create .js files for each ts files and it will continue to watch for changes in the project directory

typescript.PNG

Conclusion

In this section we have seen the design goals of TypeScript and to setup a development env. We will dig deeper in the upcoming blogs.

All the coding that will be done in this series of blogs can be found here