Casting: Typescript Repl in Node - Js
Casting: Typescript Repl in Node - Js
You can perform explicit casting through angle brackets, for instance:
var derived: MyInterface;
(<ImplementingClass>derived).someSpecificMethod();
This example shows a derived class which is treated by the compiler as a MyInterface.
Without the
casting on the second line the compiler would thrown an exception as it does not
understand
someSpecificMethod() , but casting through <ImplementingClass>derived suggests the compiler
what to
do.
Another way of casting in Typescript is using the as keyword:
var derived: MyInterface;
(derived as ImplementingClass).someSpecificMethod();
Since Typescript 1.6, the default is using the as keyword, because using <> is
ambiguous in .jsx
files. This is mentioned in Typescript official documentation.
Classes
Classes can be defined and used in TypeScript code. To learn more about classes,
see the
Classes documentation page.
TypeScript REPL in Node.js
For use TypeScript REPL in Node.js you can use tsun package
https://riptutorial.com/ 7
Install it globally with
npm install -g tsun
and run in your terminal or command prompt with tsun command
Usage example:
$ tsun
TSUN : TypeScript Upgraded Node
type in TypeScript expression to evaluate
type :help for commands in repl
$ function multiply(x, y) {
..return x * y;
..}
undefined
$ multiply(3, 4)
12
Running TypeScript using ts-node
ts-node is an npm package which allows the user to run typescript files directly,
without the need
for precompilation using tsc. It also provides REPL.
Install ts-node globally using
npm install -g ts-node
ts-node does not bundle typescript compiler, so you might need to install it.
npm install -g typescript
Executing script
To execute a script named main.ts, run
ts-node main.ts
// main.ts
console.log("Hello world");
Example usage
$ ts-node main.ts
Hello world
Running REPL
To run REPL run command ts-node
https://riptutorial.com/ 8
Example usage
$ ts-node
> const sum = (a, b): number => a + b;
undefined
> sum(2, 2)
4
> .exit
To exit REPL use command .exit or press CTRL+C twice.
Read Getting started with TypeScript online:
https://riptutorial.com/typescript/topic/764/gettingstarted-
with-typescript
https://riptutorial.com/ 9
Chapter 2: Arrays
Examples
Finding Object in Array
Using find()
const inventory = [
{name: 'apples', quantity: 2},
{name: 'bananas', quantity: 0},
{name: 'cherries', quantity: 5}
];
function findCherries(fruit) {
return fruit.name === 'cherries';
}
inventory.find(findCherries); // { name: 'cherries', quantity: 5 }
/* OR */
inventory.find(e => e.name === 'apples'); // { name: 'apples', quantity: 2 }
Read Arrays online: https://riptutorial.com/typescript/topic/9562/arrays
https://riptutorial.com/ 10
Chapter 4: Classes
Introduction
TypeScript, like ECMA Script 6, support object-oriented programming using
classes. This
contrasts with older JavaScript versions, which only supported prototype-based
inheritance chain.
The class support in TypeScript is similar to that of languages like Java and C#, in
that classes
may inherit from other classes, while objects are instantiated as class instances.
Also similar to those languages, TypeScript classes may implement interfaces or
make use of
generics.
Examples
Simple class
class Car {
public position: number = 0;
private speed: number = 42;
move() {
this.position += this.speed;
}
}
In this example, we declare a simple class Car. The class has three members: a
private property
speed, a public property position and a public method move. Note that each member is
public by
default. That's why move() is public, even if we didn't use the public keyword.
var car = new Car(); // create an instance of Car
car.move(); // call a method
console.log(car.position); // access a public property
Basic Inheritance
class Car {
public position: number = 0;
protected speed: number = 42;
move() {
this.position += this.speed;
}
}
class SelfDrivingCar extends Car {
move() {
// start moving around :-)
https://riptutorial.com/ 14
super.move();
super.move();
}
}
This examples shows how to create a very simple subclass of the Car class using
the extends
keyword. The SelfDrivingCar class overrides the move() method and uses the base class
implemention using super.
Constructors
In this example we use the constructor to declare a public property position and a
protected
property speed in the base class. These properties are called Parameter properties.
They let us
declare a constructor parameter and a member in one place.
One of the best things in TypeScript, is automatic assignment of constructor
parameters to the
relevant property.
class Car {
public position: number;
protected speed: number;
constructor(position: number, speed: number) {
this.position = position;
this.speed = speed;
}
move() {
this.position += this.speed;
}
}
All this code can be resumed in one single constructor:
class Car {
constructor(public position: number, protected speed: number) {}
move() {
this.position += this.speed;
}
}
And both of them will be transpiled from TypeScript (design time and compile time)
to JavaScript
with same result, but writing significantly less code:
var Car = (function () {
function Car(position, speed) {
this.position = position;
this.speed = speed;
}
Car.prototype.move = function () {
this.position += this.speed;
};
return Car;
https://riptutorial.com/ 15
}());
Constructors of derived classes have to call the base class constructor with super().
class SelfDrivingCar extends Car {
constructor(startAutoPilot: boolean) {
super(0, 42);
if (startAutoPilot) {
this.move();
}
}
}
let car = new SelfDrivingCar(true);
console.log(car.position); // access the public property position
Accessors
In this example, we modify the "Simple class" example to allow access to the speed
property.
Typescript accessors allow us to add additional code in getters or setters.
class Car {
public position: number = 0;
private _speed: number = 42;
private _MAX_SPEED = 100
move() {
this.position += this._speed;
}
get speed(): number {
return this._speed;
}
set speed(value: number) {
this._speed = Math.min(value, this._MAX_SPEED);
}
}
let car = new Car();
car.speed = 120;
console.log(car.speed); // 100
Abstract Classes
abstract class Machine {
constructor(public manufacturer: string) {
}
// An abstract class can define methods of it's own, or...
summary(): string {
return `${this.manufacturer} makes this machine.`;
}
// Require inheriting classes to implement methods
https://riptutorial.com/ 16
abstract moreInfo(): string;
}
class Car extends Machine {
constructor(manufacturer: string, public position: number, protected speed: number) {
super(manufacturer);
}
move() {
this.position += this.speed;
}
moreInfo() {
return `This is a car located at ${this.position} and going ${this.speed}mph!`;
}
}
let myCar = new Car("Konda", 10, 70);
myCar.move(); // position is now 80
console.log(myCar.summary()); // prints "Konda makes this machine."
console.log(myCar.moreInfo()); // prints "This is a car located at 80 and going 70mph!"
Abstract classes are base classes from which other classes can extend. They
cannot be
instantiated themselves (i.e. you cannot do new Machine("Konda")).
The two key characteristics of an abstract class in Typescript are:
1. They can implement methods of their own.
2. They can define methods that inheriting classes must implement.
For this reason, abstract classes can conceptually be considered a combination
of an interface
and a class.
Monkey patch a function into an existing class
Sometimes it's useful to be able to extend a class with new functions. For example
let's suppose
that a string should be converted to a camel case string. So we need to tell
TypeScript, that String
contains a function called toCamelCase, which returns a string.
interface String {
toCamelCase(): string;
}
Now we can patch this function into the String implementation.
String.prototype.toCamelCase = function() : string {
return this.replace(/[^a-z ]/ig, '')
.replace(/(?:^\w|[A-Z]|\b\w|\s+)/g, (match: any, index: number) => {
return +match === 0 ? "" : match[index === 0 ? 'toLowerCase' : 'toUpperCase']();
});
}
If this extension of String is loaded, it's usable like this:
https://riptutorial.com/ 17
"This is an example".toCamelCase(); // => "thisIsAnExample"
Transpilation
Given a class SomeClass, let's see how the TypeScript is transpiled into JavaScript.
TypeScript source
class SomeClass {
public static SomeStaticValue: string = "hello";
public someMemberValue: number = 15;
private somePrivateValue: boolean = false;
constructor () {
SomeClass.SomeStaticValue = SomeClass.getGoodbye();
this.someMemberValue = this.getFortyTwo();
this.somePrivateValue = this.getTrue();
}
public static getGoodbye(): string {
return "goodbye!";
}
public getFortyTwo(): number {
return 42;
}
private getTrue(): boolean {
return true;
}
}
JavaScript source
When transpiled using TypeScript v2.2.2, the output is like so:
var SomeClass = (function () {
function SomeClass() {
this.someMemberValue = 15;
this.somePrivateValue = false;
SomeClass.SomeStaticValue = SomeClass.getGoodbye();
this.someMemberValue = this.getFortyTwo();
this.somePrivateValue = this.getTrue();
}
SomeClass.getGoodbye = function () {
return "goodbye!";
};
SomeClass.prototype.getFortyTwo = function () {
return 42;
};
SomeClass.prototype.getTrue = function () {
https://riptutorial.com/ 18
return true;
};
return SomeClass;
}());
SomeClass.SomeStaticValue = "hello";
Observations
• The modification of the class' prototype is wrapped inside an IIFE.
• Member variables are defined inside the main class function.
Static properties are added directly to the class object, whereas instance properties
are
added to the prototype.
•
Read Classes online: https://riptutorial.com/typescript/topic/1560/classes
https://riptutorial.com/ 19
Chapter 6: Debugging
Introduction
There are two ways of running and debugging TypeScript:
Transpile to JavaScript, run in node and use mappings to link back to the
TypeScript source files
or
Run TypeScript directly using ts-node
This article describes both ways using Visual Studio Code and WebStorm. All
examples presume
that your main file is index.ts.
Examples
JavaScript with SourceMaps in Visual Studio Code
In the tsconfig.json set
"sourceMap": true,
to generate mappings alongside with js-files from the TypeScript sources using the
tsc command.
The launch.json file:
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceRoot}\\index.js",
"cwd": "${workspaceRoot}",
"outFiles": [],
"sourceMaps": true
}
]
}
This starts node with the generated index.js (if your main file is index.ts) file and
the debugger in
Visual Studio Code which halts on breakpoints and resolves variable values within
your TypeScript
code.
JavaScript with SourceMaps in WebStorm
Create a Node.js debug configuration and use index.js as Node parameters.
https://riptutorial.com/ 22
TypeScript with ts-node in Visual Studio Code
Add ts-node to your TypeScript project:
npm i ts-node
Add a script to your package.json:
"start:debug": "ts-node --inspect=5858 --debug-brk --ignore false index.ts"
The launch.json needs to be configured to use the node2 type and start npm running
the
start:debug script:
{
"version": "0.2.0",
"configurations": [
{
"type": "node2",
"request": "launch",
"name": "Launch Program",
"runtimeExecutable": "npm",
"windows": {
"runtimeExecutable": "npm.cmd"
},
https://riptutorial.com/ 23
"runtimeArgs": [
"run-script",
"start:debug"
],
"cwd": "${workspaceRoot}/server",
"outFiles": [],
"port": 5858,
"sourceMaps": true
}
]
}
TypeScript with ts-node in WebStorm
Add this script to your package.json :
"start:idea": "ts-node %NODE_DEBUG_OPTION% --ignore false index.ts",
Right click on the script and select Create 'test:idea'... and confirm with 'OK' to
create the debug
configuration:
https://riptutorial.com/ 24
Start the debugger using this configuration:
Read Debugging online: https://riptutorial.com/typescript/topic/9131/debugging
https://riptutorial.com/ 25
Chapter 7: Enums
Examples
How to get all enum values
enum SomeEnum { A, B }
let enumValues:Array<string>= [];
for(let value in SomeEnum) {
if(typeof SomeEnum[value] === 'number') {
enumValues.push(value);
}
}
enumValues.forEach(v=> console.log(v))
//A
//B
Enums with explicit values
By default all enum values are resolved to numbers. Let's say if you have something
like
enum MimeType {
JPEG,
PNG,
PDF
}
the real value behind e.g. MimeType.PDF will be 2.
But some of the time it is important to have the enum resolve to a different type.
E.g. you receive
the value from backend / frontend / another system which is definitely a string. This
could be a
pain, but luckily there is this method:
enum MimeType {
JPEG = <any>'image/jpeg',
PNG = <any>'image/png',
PDF = <any>'application/pdf'
}
This resolves the MimeType.PDF to application/pdf.
Since TypeScript 2.4 it's possible to declare string enums:
enum MimeType {
JPEG = 'image/jpeg',
PNG = 'image/png',
PDF = 'application/pdf',
https://riptutorial.com/ 26
}
You can explicitly provide numeric values using the same method
enum MyType {
Value = 3,
ValueEx = 30,
ValueEx2 = 300
}
Fancier types also work, since non-const enums are real objects at runtime, for
example
enum FancyType {
OneArr = <any>[1],
TwoArr = <any>[2, 2],
ThreeArr = <any>[3, 3, 3]
}
becomes
var FancyType;
(function (FancyType) {
FancyType[FancyType["OneArr"] = [1]] = "OneArr";
FancyType[FancyType["TwoArr"] = [2, 2]] = "TwoArr";
FancyType[FancyType["ThreeArr"] = [3, 3, 3]] = "ThreeArr";
})(FancyType || (FancyType = {}));
Custom enum implementation: extends for enums
Sometimes it is required to implement Enum on your own. E.g. there is no clear
way to extend
other enums. Custom implementation allows this:
class Enum {
constructor(protected value: string) {}
public toString() {
return String(this.value);
}
public is(value: Enum | string) {
return this.value = value.toString();
}
}
class SourceEnum extends Enum {
public static value1 = new SourceEnum('value1');
public static value2 = new SourceEnum('value2');
}
class TestEnum extends SourceEnum {
public static value3 = new TestEnum('value3');
public static value4 = new TestEnum('value4');