Typescript is a superset of javascript which means any javascript code is a valid typescript but typescript has some additional features which are not in javascript e.g strong typing (specifying the type of a variable when declared, which can make our application more predictable and easily debuggable), brings object oriented features into javascript and many more.
Browsers does not support typescript so we need to transpile our typescript into javascript.
We need install typescript on our system before we can use it, run the code below in your terminal to install typescript:
sudo npm install -g typescript
Open your text editor and create a new file main.ts
function log(message) {
console(message);
}
let message = 'Hello Typescript';
log(message);
Run below command in the terminal under your project directory
tsc main.ts
The tsc main.ts command above create a new file main.js which is the javascript version of the main.ts that was transpiled.
we can run the transpiled main.js from the terminal using the command below
node main.js
Note: You do not need to manually run tsc main.js within an angular application because ng serve does that automatically for you.
Typescript Types:
We have different types in typescript which includes:
let a: number //e.g 1, 2, 3
let b: boolean //e.g true, false
let c: string //e.g "abel agoi"
let d: any //this can take any other types
let e: number[] //array of numbers e.g [1, 3, 54]
let f: any[] //any array e.g [1, "abel agoi", true]
Note: There is another type called enum which I did not talk about, you can check that out yourself.
Arrow function :
In javascript, we can declare a function like below:
let log = function (message) {
console.dir(message);
}
You can also use the arrow function (=>) to achieve the same thing in typescript like below
let log = (message) => {
//we simply remove the function
console.dir(message);
}
//above can even be shorten to
let log = (message) => console.dir(message);
//and if you are only passing one parameter, it can be shorten to
let log = message => console.dir(message); //not readable though
Interfaces:
It is a bad practice to pass many parameters to a function like below:
let myFunction = (
a: number,
b: number,
c: string,
d: any,
e: number[],
f: any[]
) => {
console.log('something);
}
We can avoid this by encapsulating all the parameters into an object and pass the single object into the function using interfaces (provided by typescript) like below:
interface MyParameters {
a: number,
b: number,
c: string,
d: any,
e: number[],
f: any[]
...
...
}
let myFunction = (myParameters: MyParameters) {}
Classes:
You should make it a good practice to group related variables (properties) and functions (methods) into a single code block, which in programming is denoted as a Class. create a new file named myPoint.ts like below :
class MyPoint {
x: number;
y: string;
draw() {
//note the way we access the x property below using this
console.log(this.x);
console.log(this.y);
}
getDistanceBtw(another: AnotherPoint) {
//get distance
}
}
Accessing a class properties and methods:
Since we have grouped related properties and methods into a single class. We need to be able to access those properties and methods. We can access the properties of a method by creating instance of the class.
let myPoint = new MyPoint() //where MyPoint is the class name
myPoint.x = 2; //this is you setting the property of x
myPoint.y = "a"; //this is you setting the property of a
myPoint.draw(); //we access the draw method
We can compile and run the class by typing below command in our terminal:
tsc myPoint.ts | node myPoint.js
We need to first create an instance of the class before assigning the class properties. What if there is a better way to assign the properties on the fly when we instantiate the class? Yes, there is. The Constructor.
Constructor:
A constructor is a method that is automatically called whenever we instantiate a class. The constructor allow us to assign properties when we instantiate a class.
let myPoint = new MyPoint()
myPoint.x = 2;
myPoint.y = "a";
The above can now be shorten to below:
let myPoint = new MyPoint(2, "a");
We also need to update our class to allow for use of the constructor
class MyPoint {
x: number;
y: string;
constructor (x: number, y: string) {
this.x = x;
this.y = y;
}
draw() { //note the way we access the x property below using this
console.log(this.x);
console.log(this.y);
}
getDistanceBtw(another: AnotherPoint) {
//get distance
}
}
Optional Parameters in constructors:
What if we want to use a constructor but also make it optional? Yes, its possible. We need to use the “?” in the constructor like below. The “?” symbol allow us to declare a parameter has optional.
class MyPoint {
x: number;
y: string;
constructor (x?: number, y?: string) {
//note the "?" before ":"
this.x = x;
this.y = y;
}
draw() { //note the way we access the x property below using this
console.log(this.x);
console.log(this.y);
}
getDistanceBtw(another: AnotherPoint) {
//get distance
}
}
//The below will work for instance A of MyPoint
let myPointA = new MyPoint()
myPoint.x = 2;
myPoint.y = "a";
myPoint.draw();
//The below will work for instance B of MyPoint
let myPointB = new MyPoint(2, "b");
myPointB.draw();
//The below will work for instance A of MyPoint
let myPointC = new MyPoint(2); //note: we didnt pass parameter for Y
myPointC.draw();
Access Modifiers:
Access modifiers is a keyword we apply to a property or a member of a class to control its access from the outside. We have basically three access modifiers in typescript which are: public, protected, private. By default, all members are public, meaning they can be access/modified from outside the class. e.g setting the properties x and y to private will not allow them to be accessible outside of the class
class MyPoint {
private x: number;
private y: string;
//we can also set an access modifier on methods like below
public draw() {
//draw something
}
}
let myPoint = new MyPoint();
myPoint.x = 3;
Accessing myPoint.x instance above will cause an error because of the private keyword.
Typescript helper I love using in Constructor
We added a constructor to our class like below:
private x: number;public y: string;
constructor (x: number, y: string) {
this.x = x;
this.y = y;
}
Thanks to typescript, we can shorten the above to:
constructor (private x: number, public y: string) {}
Yes, that’s it. Typescript will automatically handle the rest for us(bet you will see this a lot in an angular app). We wont need the:
private x: number;
public y: string;
and
this.x = x;
this.y = y;
Getters and Setters
Assume the current state of our MyPoint class is like below
class MyPoint {
constructor (private x?: number, private y?: string) {}
draw() {
//draw something
}
drawAnotherThing() {
//draw another thing
}
}
We sure know that we will not be able to access the x and y properties of MyPoint class because of the private modifier applied, but should in case we want to be able to access them, we need use a getter and setter like below:
class MyPoint {
constructor (private x?: number, private y?: string) {}
getX() {
//this is use to get X
return this.x;
}
setX(value) {
//this is use to set X
this.x = value;
}
}
since we can not set x directly after initialising the MyPoint class,
we use setX() (setters) to set the value of X like below:
let myPoint = new MyPoint();
myPoint.setX = 4;
console.log( myPoint.getX() ); //this will give us 4;
Setters and Getters can let you set constraints on the value of X when setting and getting the value.
Another typescript helper I love to use with Setters and Getters
Instead of using myPoint.getX() to get the value of X, what if I can do something like
myPoint.X = 4; //accessing X like its a property when its actually a getter
Then I need to create a space before the getter and setter function name
class MyPoint {
constructor (private x?: number, private y?: string) {}
get X() {
//note the space before the X
return this.x;
}
set X(value) {
//note the space before the Y
this.x = value;
}
}
It is also a common practice to name our properties beginning with underscore (_) so we can have something like below
class MyPoint {
constructor (private _x?: number, private _y?: string) {}
get x() {
//note the space before the X
return this._x;
}
set x(value) {
//note the space before the Y
this._x = value;
}
}
Modules
A real world application will have more than one class. We have to be able to make our class in such a way that it can be use in another class hence the need for modularisation. First let us modify our myPoint.ts class to below:
export class MyPoint { //note the export keyword added
constructor (private _x?: number, private _y?: string) {}
get x() {
return this._x;
}
set x() {
//note the space before the Y
}
draw() {
}
}
The export keyword will make the MyPoint.ts visible and to be use within another class that import it.
We need to import MyPoint.ts class within main.ts to be able to use it.
import { MyPoint } from './myPoint';
class Main {
let MyPoint = new MyPoint(4, 'good to go');
MyPoint.draw();
}
Note: main.ts and myPoint.ts are in the same directory.
I am happy to share with you the basic typescript you need know to start learning Angular.
Thanks for reading
Top comments (2)
This is a great intro to TypeScript!
I linked out to your article in my article about Dart, TypeScript, and Angular. I hope that's ok with you. If not, reach out to me and I can remove it.
Aww, So kind of you. It is okay. Thanks