Typescript 2
Typescript 2
#typescript
Table of Contents
About 1
Remarks 2
Versions 2
Examples 3
Background 3
IDEs 3
Visual Studio 3
WebStorm 4
IntelliJ IDEA 4
Sublime Text 4
Install Node.js 4
Installation channels 5
Hello World 5
Basic syntax 6
Type declarations 6
Casting 7
Classes 7
Chapter 2: Arrays 10
Examples 10
Finding Object in Array 10
Using find() 10
Parameters 11
Examples 11
Chapter 4: Classes 14
Introduction 14
Examples 14
Simple class 14
Basic Inheritance 14
Constructors 15
Accessors 16
Abstract Classes 16
Transpilation 18
TypeScript source 18
JavaScript source 18
Observations 19
Introduction 20
Examples 20
Chapter 6: Debugging 22
Introduction 22
Examples 22
Examples 26
Chapter 8: Functions 29
Remarks 29
Examples 29
Types of Functions 29
Function as a parameter 30
Chapter 9: Generics 33
Syntax 33
Remarks 33
Examples 33
Generic Interfaces 33
Generic Class 34
Generics Constraints 35
Generic Functions 35
Chapter 10: How to use a javascript library without a type definition file 38
Introduction 38
Examples 38
Syntax 40
Remarks 40
Examples 40
Remarks 44
Examples 44
Browserify 44
Install 44
Using API 44
Grunt 45
Install 45
Basic Gruntfile.js 45
Gulp 45
Install 45
Basic gulpfile.js 45
Webpack 46
Install 46
Basic webpack.config.js 46
webpack 1.x 47
MSBuild 47
NuGet 48
Chapter 13: Interfaces 49
Introduction 49
Syntax 49
Remarks 49
Examples 50
Class Interface 50
Extending Interface 51
Generic Interfaces 52
Syntax 56
Parameters 56
Remarks 56
Examples 56
Example of Mixins 56
Examples 58
Exporting/Importing declarations 58
Re-export 59
Examples 62
Non-null assertions 63
Syntax 65
Remarks 65
Overview 65
Using tsconfig.json 65
Details 65
Schema 66
Examples 66
compileOnSave 68
Comments 68
preserveConstEnums 69
Introduction 71
Examples 71
Remarks 74
Examples 74
2 static class variable example - count how many time method is being invoked 74
Syntax 76
Examples 76
Boolean 76
Number 76
String 76
Array 76
Enum 77
Any 77
Void 77
Tuple 77
Intersection Types 82
const Enum 83
Parameters 85
Remarks 85
Examples 85
Directive 85
Simple example 86
Component 87
Examples 89
Introduction 92
Examples 92
Steps. 92
Examples 94
Alsatian 94
chai-immutable plugin 94
tape 95
jest (ts-jest) 96
Code coverage 97
Syntax 100
Remarks 100
Examples 100
Chapter 27: Using Typescript with React (JS & native) 103
Examples 103
Introduction 106
Examples 106
HTML example using requireJS CDN to include an already compiled TypeScript file. 106
tsconfig.json example to compile to view folder using requireJS import style. 106
Examples 107
webpack.config.js 107
Introduction 109
Remarks 109
Examples 110
Safety 110
Readability 110
Tooling 110
Credits 112
About
You can share this PDF with anyone you feel could benefit from it, downloaded the latest version
from: typescript
It is an unofficial and free TypeScript ebook created for educational purposes. All the content is
extracted from Stack Overflow Documentation, which is written by many hardworking individuals at
Stack Overflow. It is neither affiliated with Stack Overflow nor official TypeScript.
The content is released under Creative Commons BY-SA, and the list of contributors to each
chapter are provided in the credits section at the end of this book. Images may be copyright of
their respective owners unless otherwise specified. All trademarks and registered trademarks are
the property of their respective company owners.
Use the content presented in this book at your own risk; it is not guaranteed to be correct nor
accurate, please send your feedback and corrections to [email protected]
https://riptutorial.com/ 1
Chapter 1: Getting started with TypeScript
Remarks
TypeScript aims to be a superset of JavaScript that transpiles to JavaScript. By generating
ECMAScript compliant code, TypeScript can introduce new language features while retaining
compatibility with existing JavaScript engines. ES3, ES5 and ES6 are currently supported targets.
Optional types are a primary feature. Types allow static checking with the goal of finding errors
early and can enhance tooling with features like code refactoring.
TypeScript is an open source and cross platform programming language developed by Microsoft.
The source code is available on GitHub.
Versions
2.4.1 2017-06-27
2.3.2 2017-04-28
2.3.1 2017-04-25
2.2.2 2017-03-13
2.2 2017-02-17
2.1.6 2017-02-07
2.1.5 2017-01-05
2.1.4 2016-12-05
2.0.8 2016-11-08
2.0.7 2016-11-03
2.0.6 2016-10-23
2.0.5 2016-09-22
https://riptutorial.com/ 2
Version Release Date
1.8.10 2016-04-09
1.8.9 2016-03-16
1.8.5 2016-03-02
1.8.2 2016-02-17
1.7.5 2015-12-14
1.7 2015-11-20
1.6 2015-09-11
1.5.4 2015-07-15
1.5 2015-07-15
1.4 2015-01-13
1.3 2014-10-28
1.1.0.1 2014-09-23
Examples
Installation and setup
Background
TypeScript is a typed superset of JavaScript that compiles directly to JavaScript code. TypeScript
files commonly use the .ts extension. Many IDEs support TypeScript without any other setup
required, but TypeScript can also be compiled with the TypeScript Node.JS package from the
command line.
IDEs
Visual Studio
• Visual Studio 2015 includes TypeScript.
• Visual Studio 2013 Update 2 or later includes TypeScript, or you can download TypeScript for
earlier versions.
https://riptutorial.com/ 3
Visual Studio Code
• Visual Studio Code (vscode) provides contextual autocomplete as well as refactoring and
debugging tools for TypeScript. vscode is itself implemented in TypeScript. Available for Mac
OS X, Windows and Linux.
WebStorm
• WebStorm 2016.2 comes with TypeScript and a built-in compiler. [Webstorm is not free]
IntelliJ IDEA
• IntelliJ IDEA 2016.2 has support for Typescript and a compiler via a plugin maintained by
the Jetbrains team. [IntelliJ is not free]
Sublime Text
• Sublime Text supports TypeScript with the typescript package.
or
https://riptutorial.com/ 4
Installation channels
tsc my-code.ts
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"sourceMap": false,
"pretty": true
},
"exclude": [
"node_modules"
]
}
With a tsconfig.json file placed at the root of your TypeScript project, you can use the tsc
command to run the compilation.
Hello World
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet(): string {
return this.greeting;
}
https://riptutorial.com/ 5
};
Here we have a class, Greeter, that has a constructor and a greet method. We can construct an
instance of the class using the new keyword and pass in a string we want the greet method to
output to the console. The instance of our Greeter class is stored in the greeter variable which we
then us to call the greet method.
Basic syntax
TypeScript is a typed superset of JavaScript, which means that all JavaScript code is valid
TypeScript code. TypeScript adds a lot of new features on top of that.
TypeScript makes JavaScript more like a strongly-typed, object-oriented language akin to C# and
Java. This means that TypeScript code tends to be easier to use for large projects and that code
tends to be easier to understand and maintain. The strong typing also means that the language
can (and is) precompiled and that variables cannot be assigned values that are out of their
declared range. For instance, when a TypeScript variable is declared as a number, you cannot
assign a text value to it.
This strong typing and object orientation makes TypeScript easier to debug and maintain, and
those were two of the weakest points of standard JavaScript.
Type declarations
You can add type declarations to variables, function parameters and function return types. The
type is written after a colon following the variable name, like this: var num: number = 5; The
compiler will then check the types (where possible) during compilation and report type errors.
https://riptutorial.com/ 6
○ {name: string, age: number} - object with name and age attributes
○ {[key: string]: number} - a dictionary of numbers indexed by string
• enum - { Red = 0, Blue, Green } - enumeration mapped to numbers
• Function. You specify types for the parameters and return value:
○ (param: number) => string - function taking one number parameter returning string
○ () => number - function with no parameters returning an number.
○ (a: string, b?: boolean) => void - function taking a string and optionally a boolean with
no return value.
• any - Permits any type. Expressions involving any are not type checked.
• void - represents "nothing", can be used as a function return value. Only null and undefined
are part of the void type.
• never
○ let foo: never; -As the type of variables under type guards that are never true.
○ function error(message: string): never { throw new Error(message); } - As the return
type of functions that never return.
• null- type for the value null. null is implicitly part of every type, unless strict null checks are
enabled.
Casting
You can perform explicit casting through angle brackets, for instance:
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.
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.
For use TypeScript REPL in Node.js you can use tsun package
https://riptutorial.com/ 7
Install it globally with
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
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.
ts-node does not bundle typescript compiler, so you might need to install it.
Executing script
ts-node main.ts
// main.ts
console.log("Hello world");
Example usage
$ ts-node main.ts
Hello world
Running REPL
https://riptutorial.com/ 8
Example usage
$ ts-node
> const sum = (a, b): number => a + b;
undefined
> sum(2, 2)
4
> .exit
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';
}
/* OR */
https://riptutorial.com/ 10
Chapter 3: Class Decorator
Parameters
Parameter Details
Examples
Basic class decorator
A class decorator is just a function that takes the class as its only argument and returns it after
doing something with it:
function log<T>(target: T) {
// Return target
return target;
@log
class Person {
private _name: string;
public constructor(name: string) {
this._name = name;
}
public greet() {
return this._name;
}
}
This time we are going to declare a class decorator that will add some metadata to a class when
we applied to it:
https://riptutorial.com/ 11
// Return target
return target;
@addMetadata
class Person {
private _name: string;
public constructor(name: string) {
this._name = name;
}
public greet() {
return this._name;
}
}
console.log(getMetadataFromClass(Person));
The decorator is applied when the class is declared not when we create instances of the class.
This means that the metadata is shared across all the instances of a class:
console.log(getMetadataFromInstance(person1));
console.log(getMetadataFromInstance(person2));
// Add metadata
target.__customMetadata = metadata;
// Return target
return target;
}
}
The addMetadata takes some arguments used as configuration and then returns an unnamed
https://riptutorial.com/ 12
function which is the actual decorator. In the decorator we can access the arguments because
there is a closure in place.
console.log(getMetadataFromInstance(Person));
{ guid: "417c6ec7-ec05-4954-a3c6-73a0d7f9f5bf" }
https://riptutorial.com/ 13
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.
Basic Inheritance
class Car {
public position: number = 0;
protected speed: number = 42;
move() {
this.position += this.speed;
}
}
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;
move() {
this.position += this.speed;
}
}
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:
https://riptutorial.com/ 15
}());
Constructors of derived classes have to call the base class constructor with super().
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;
}
Abstract Classes
https://riptutorial.com/ 16
abstract moreInfo(): string;
}
move() {
this.position += this.speed;
}
moreInfo() {
return `This is a car located at ${this.position} and going ${this.speed}mph!`;
}
}
Abstract classes are base classes from which other classes can extend. They cannot be
instantiated themselves (i.e. you cannot do new Machine("Konda")).
For this reason, abstract classes can conceptually be considered a combination of an interface
and a 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;
}
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 {
constructor () {
SomeClass.SomeStaticValue = SomeClass.getGoodbye();
this.someMemberValue = this.getFortyTwo();
this.somePrivateValue = this.getTrue();
}
JavaScript source
When transpiled using TypeScript v2.2.2, the output is like so:
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.
https://riptutorial.com/ 19
Chapter 5: Configure typescript project to
compile all files in typescript.
Introduction
creating your first .tsconfig configuration file which will tell the TypeScript compiler how to treat
your .ts files
Examples
Typescript Configuration file setup
• Now, You can compile all typescripts by command "tsc". it will automatically create ".js" file
of your typescript file.
https://riptutorial.com/ 20
• If you will create another typescript and hit "tsc" command in command prompt or terminal
javascript file will be automatically created for typescript file.
Thank you,
https://riptutorial.com/ 21
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
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
"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.
https://riptutorial.com/ 22
TypeScript with ts-node in Visual Studio Code
npm i ts-node
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
}
]
}
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:
https://riptutorial.com/ 25
Chapter 7: Enums
Examples
How to get all enum values
enum SomeEnum { A, B }
enumValues.forEach(v=> console.log(v))
//A
//B
By default all enum values are resolved to numbers. Let's say if you have something like
enum MimeType {
JPEG,
PNG,
PDF
}
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'
}
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 = {}));
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);
}
https://riptutorial.com/ 27
return test === TestEnum.value2;
}
console.log(value1 + 'hello');
console.log(value1.toString() === 'value1');
console.log(value1.is('value1'));
console.log(!TestEnum.value3.is(TestEnum.value3));
console.log(check(TestEnum.value2));
// this works but perhaps your TSLint would complain
// attention! does not work with ===
// use .is() instead
console.log(TestEnum.value1 == <any>'value1');
enum SourceEnum {
value1 = <any>'value1',
value2 = <any>'value2'
}
enum AdditionToSourceEnum {
value3 = <any>'value3',
value4 = <any>'value4'
}
console.log(TestEnum.value1);
console.log(TestEnum.value2 === <any>'value2');
console.log(check(TestEnum.value2));
console.log(check(TestEnum.value3));
https://riptutorial.com/ 28
Chapter 8: Functions
Remarks
Typescript documentation link for Functions
Examples
Optional and Default Parameters
Optional Parameters
In TypeScript, every parameter is assumed to be required by the function. You can add a ? at the
end of a parameter name to set it as optional.
Default Parameters
If the user passes undefined or doesn't specify an argument, the default value will be assigned.
These are called default-initialized parameters.
For example, "Smith" is the default value for the lastName parameter.
Types of Functions
Named functions
function multiply(a, b) {
return a * b;
}
https://riptutorial.com/ 29
Anonymous functions
Function as a parameter
interface IConstructor {
new();
}
Or with parameters:
interface INumberConstructor {
new(num: number);
}
https://riptutorial.com/ 30
function foo<T, U>(contructorFunc: ITConstructor<T, U>, item: T): U {
return new contructorFunc(item);
}
If we want to receive a simple function and not a constructor it's almost the same:
interface IFunction {
(): void;
}
Or with parameters:
interface INumberFunction {
(num: number): string;
}
A TypeScript function can take in parameters of multiple, predefined types using union types.
whatTime(1,30) //'1:30'
whatTime('1',30) //'1:30'
https://riptutorial.com/ 31
whatTime(1,'30') //'1:30'
whatTime('1','30') //'1:30'
Typescript treats these parameters as a single type that is a union of the other types, so your
function must be able to handle parameters of any type that is in the union.
function addTen(start:number|string):number{
if(typeof number === 'string'){
return parseInt(number)+10;
}else{
else return number+10;
}
}
https://riptutorial.com/ 32
Chapter 9: Generics
Syntax
• The generic types declared within the triangle brackets: <T>
• Constrainting the generic types is done with the extends keyword: <T extends Car>
Remarks
The generic parameters are not available at runtime, they are just for the compile time. This
means you can't do something like this:
However, class information is still preserved, so you can still test for the type of a variable as you
have always been able to:
Examples
Generic Interfaces
https://riptutorial.com/ 33
var result: IResult<string> = ....
var error: string = result.error;
clone(): IResult<T>;
}
Generic Class
class Result<T> {
https://riptutorial.com/ 34
constructor(public wasSuccessful: boolean, public error: T) {
}
Generics Constraints
Simple constraint:
interface IRunnable {
run(): void;
}
interface IRunnble<U> {
run(): U;
}
interface IRunnble<V> {
run(parameter: U): V;
}
Generic Functions
In interfaces:
https://riptutorial.com/ 35
interface IRunner {
runSafe<T extends IRunnable>(runnable: T): void;
}
In classes:
Simple functions:
With TypeScript 1.8 it becomes possible for a type parameter constraint to reference type
parameters from the same type parameter list. Previously this was an error.
https://riptutorial.com/ 36
}
let x = { a: 1, b: 2, c: 3, d: 4 };
assign(x, { b: 10, d: 20 });
assign(x, { e: 0 }); // Error
https://riptutorial.com/ 37
Chapter 10: How to use a javascript library
without a type definition file
Introduction
While some existing JavaScript libraries have type definition files, there are many that don't.
Examples
Declare an any global
It is sometimes easiest to just declare a global of type any, especially in simple projects.
If jQuery didn't have type declarations (it does), you could put
For more complicated projects, or in cases where you intend to gradually type a dependency, it
may be cleaner to create a module.
// place in jquery.d.ts
declare let $: any;
export default $;
And then in any file in your project, you can import this definition with:
If the library has multiple top-level variables, export and import by name instead:
// place in jquery.d.ts
declare module "jquery" {
let $: any;
let jQuery: any;
https://riptutorial.com/ 38
export { $ };
export { jQuery };
}
$.doThing();
jQuery.doOtherThing();
If you just want to indicate the intent of an import (so you don't want to declare a global) but don't
wish to bother with any explicit definitions, you can import an ambient module.
Anything imported from the declared module (like $ and jQuery) above will be of type any
Read How to use a javascript library without a type definition file online:
https://riptutorial.com/typescript/topic/8249/how-to-use-a-javascript-library-without-a-type-
definition-file
https://riptutorial.com/ 39
Chapter 11: Importing external libraries
Syntax
• import {component} from 'libName'; // Will import the class "component"
• import {component as c} from 'libName'; // Will import the class "component" into a "c"
object
• import component from 'libname'; // Will import the default export from libName
• import * as lib from 'libName'; // Will import everything from libName into a "lib" object
• import lib = require('libName'); // Will import everything from libName into a "lib" object
• const lib: any = require('libName'); // Will import everything from libName into a "lib"
object
• import 'libName'; // Will import libName module for its side effects only
Remarks
It might seem that the syntax
and
Let us consider that we want to import a class Person exported with TypeScript-specific export =
syntax :
class Person {
...
}
export = Person;
In this case it is not possible to import it with es6 syntax (we would get an error at compile time),
TypeScript-specific import = syntax must be used.
The converse is true: classic modules can be imported with the second syntax, so, in a way, the
last syntax is more powerful since it is able to import all exports.
Examples
https://riptutorial.com/ 40
Importing a module from npm
If you have a type definition file (d.ts) for the module, you can use an import statement.
import _ = require('lodash');
If you don't have a definition file for the module, TypeScript will throw an error on compilation
because it cannot find the module you are trying to import.
In this case, you can import the module with the normal runtime require function. This returns it as
the any type, however.
// The _ variable is of type any, so TypeScript will not perform any type checking.
const _: any = require('lodash');
As of TypeScript 2.0, you can also use a shorthand ambient module declaration in order to tell
TypeScript that a module exists when you don't have a type definition file for the module.
TypeScript won't be able to provide any meaningful typechecking in this case though.
// you can now import from lodash in any way you wish:
import { flatten } from "lodash";
import * as _ from "lodash";
As of TypeScript 2.1, the rules have been relaxed even further. Now, as long as a module exists in
your node_modules directory, TypeScript will allow you to import it, even with no module declaration
anywhere. (Note that if using the --noImplicitAny compiler option, the below will still generate a
warning.)
but in case if you want use types from other repos then can be used old way:
Typings is an npm package that can automatically install type definition files into a local project. I
recommend that you read the quickstart.
https://riptutorial.com/ 41
npm install -global typings
1. The first step is to search for the package used by the project
2. Then decide which source you should install from. I use dt which stands for DefinitelyTyped
a GitHub repo where the community can edit typings, it's also normally the most recently
updated.
Let's break down the last command. We are installing the DefinitelyTyped version of lodash as a
global typings file in our project and saving it as a dependency in the typings.json. Now wherever
we import lodash, typescript will load the lodash typings file.
4. If we want to install typings that will be used for development environment only, we can
supply the --save-dev flag:
Although modules are ideal, if the library you are using is referenced by a global variable (like $ or
_), because it was loaded by a script tag, you can create an ambient declaration in order to refer
to it:
With the 2.x versions of typescript, typings are now available from the npm @types repository.
These are automatically resolved by the typescript compiler and are much simpler to use.
To install a type definition you simply install it as a dev dependency in your projects package.json
e.g.
https://riptutorial.com/ 42
npm i -S lodash
npm i -D @types/lodash
https://riptutorial.com/ 43
Chapter 12: Integrating with Build Tools
Remarks
For more information you can go on official web page typescript integrating with build tools
Examples
Install and configure webpack + loaders
Installation
webpack.config.js
module.exports = {
entry: {
app: ['./src/'],
},
output: {
path: __dirname,
filename: './dist/[name].js',
},
resolve: {
extensions: ['', '.js', '.ts'],
},
module: {
loaders: [{
test: /\.ts(x)$/, loaders: ['ts-loader'], exclude: /node_modules/
}],
}
};
Browserify
Install
npm install tsify
https://riptutorial.com/ 44
Using API
var browserify = require("browserify");
var tsify = require("tsify");
browserify()
.add("main.ts")
.plugin("tsify", { noImplicitAny: true })
.bundle()
.pipe(process.stdout);
Grunt
Install
npm install grunt-ts
Basic Gruntfile.js
module.exports = function(grunt) {
grunt.initConfig({
ts: {
default : {
src: ["**/*.ts", "!node_modules/**/*.ts"]
}
}
});
grunt.loadNpmTasks("grunt-ts");
grunt.registerTask("default", ["ts"]);
};
Gulp
Install
npm install gulp-typescript
Basic gulpfile.js
https://riptutorial.com/ 45
var gulp = require("gulp");
var ts = require("gulp-typescript");
gulp.task("default", function () {
var tsResult = gulp.src("src/*.ts")
.pipe(ts({
noImplicitAny: true,
out: "output.js"
}));
return tsResult.js.pipe(gulp.dest("built/local"));
});
gulp.task("default", function () {
var tsResult = tsProject.src()
.pipe(tsProject());
return tsResult.js.pipe(gulp.dest('release'));
});
Webpack
Install
npm install ts-loader --save-dev
Basic webpack.config.js
webpack 2.x, 3.x
module.exports = {
resolve: {
extensions: ['.ts', '.tsx', '.js']
},
module: {
rules: [
{
// Set up ts-loader for .ts/.tsx files and exclude any imports from
node_modules.
test: /\.tsx?$/,
https://riptutorial.com/ 46
loaders: ['ts-loader'],
exclude: /node_modules/
}
]
},
entry: [
// Set index.tsx as application entry point.
'./index.tsx'
],
output: {
filename: "bundle.js"
}
};
webpack 1.x
module.exports = {
entry: "./src/index.tsx",
output: {
filename: "bundle.js"
},
resolve: {
// Add '.ts' and '.tsx' as a resolvable extension.
extensions: ["", ".webpack.js", ".web.js", ".ts", ".tsx", ".js"]
},
module: {
loaders: [
// all files with a '.ts' or '.tsx' extension will be handled by 'ts-loader'
{ test: /\.ts(x)?$/, loader: "ts-loader", exclude: /node_modules/ }
]
}
}
Alternatives:
• awesome-typescript-loader
MSBuild
Update project file to include locally installed Microsoft.TypeScript.Default.props (at the top) and
Microsoft.TypeScript.targets (at the bottom) files:
Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft
Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript
/>
https://riptutorial.com/ 47
<!-- TypeScript configurations go here -->
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
<TypeScriptRemoveComments>false</TypeScriptRemoveComments>
<TypeScriptSourceMap>true</TypeScriptSourceMap>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
<TypeScriptRemoveComments>true</TypeScriptRemoveComments>
<TypeScriptSourceMap>false</TypeScriptSourceMap>
</PropertyGroup>
Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft
Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript
/>
</Project>
More details about defining MSBuild compiler options: Setting Compiler Options in MSBuild
projects
NuGet
More details can be found at Package Manager Dialog and using nightly builds with NuGet
https://riptutorial.com/ 48
Chapter 13: Interfaces
Introduction
An interfaces specifies a list of fields and functions that may be expected on any class
implementing the interface. Conversely, a class cannot implement an interface unless it has every
field and function specified on the interface.
The primary benefit of using interfaces, is that it allows one to use objects of different types in a
polymorphic way. This is because any class implementing the interface has at least those fields
and functions.
Syntax
• interface InterfaceName {
• parameterName: parameterType;
• optionalParameterName?: parameterType;
• }
Remarks
interface person {
id?: number;
name: string;
age: number;
}
However what if you want to represent, say, the way a person is stored in an SQL database?
Seeing as each DB entry consists of a row of shape [string, string, number] (so an array of
strings or numbers), there is no way you could represent this as an object shape, because the row
doesn't have any properties as such, it's just an array.
This is an occasion where types come in useful. Instead of specifying in every function that
accepts a row parameter function processRow(row: [string, string, number]), you can create a
separate type alias for a row and then use that in every function:
https://riptutorial.com/ 49
Official interface documentation
https://www.typescriptlang.org/docs/handbook/interfaces.html
Examples
Add functions or properties to an existing interface
Let's suppose we have a reference to the JQuery type definition and we want to extend it to have
additional functions from a plugin we included and which doesn't have an official type definition.
We can easily extend it by declaring functions added by plugin in a separate interface declaration
with the same JQuery name:
interface JQuery {
pluginFunctionThatDoesNothing(): void;
The compiler will merge all declarations with the same name into one - see declaration merging for
more details.
Class Interface
Declare public variables and methods type in the interface to define how other typescript code can
interact with it.
interface ISampleClassInterface {
sampleVariable: string;
sampleMethod(): void;
optionalVariable?: string;
}
constructor() {
this.sampleVariable = 'string value';
this.answerToLifeTheUniverseAndEverything = 42;
}
https://riptutorial.com/ 50
private answer(q: any): number {
return this.answerToLifeTheUniverseAndEverything;
}
}
The example shows how to create an interface ISampleClassInterface and a class SampleClass that
implements the interface.
Extending Interface
interface IPerson {
name: string;
age: number;
breath(): void;
}
And we want to create more specific interface that has the same properties of the person, we can
do it using the extends keyword:
One of the core benefits of Typescript is that it enforces data types of values that you are passing
around your code to help prevent mistakes.
You have this simple function that checks if two pets are compatible with each other...
checkCompatible(petOne, petTwo) {
if (petOne.species === petTwo.species &&
Math.abs(petOne.age - petTwo.age) <= 5) {
return true;
}
}
This is completely functional code, but it would be far too easy for someone, especially other
people working on this application who didn't write this function, to be unaware that they are
supposed to pass it objects with 'species' and 'age' properties. They may mistakenly try
checkCompatible(petOne.species, petTwo.species) and then be left to figure out the errors thrown
when the function tries to access petOne.species.species or petOne.species.age!
https://riptutorial.com/ 51
One way we can prevent this from happening is to specify the properties we want on the pet
parameters:
In this case, Typescript will make sure everything passed to the function has 'species' and 'age'
properties (it is okay if they have additional properties), but this is a bit of an unwieldy solution,
even with only two properties specified. With interfaces, there is a better way!
interface Pet {
species: string;
age: number;
//We can add more properties if we choose.
}
Now all we have to do is specify the type of our parameters as our new interface, like so...
... and Typescript will make sure that the parameters passed to our function contain the properties
specified in the Pet interface!
Generic Interfaces
Like classes, interfaces can receive polymorphic parameters (aka Generics) too.
interface IEvents<T> {
list: T[];
emit(event: T): void;
getAll(): T[];
}
Here, you can see that our two interfaces take some generic parameters, T and U.
https://riptutorial.com/ 52
class State<T> implements IEvents<T> {
list: T[];
constructor() {
this.list = [];
}
getAll(): T[] {
return this.list;
}
In our example, the State class will handle a generic status by using IStatus<T>. In this way, the
interface IEvent<T> will also handle a IStatus<T>.
Our State class is typed as IStatus<Code>. In this way, we are able to pass more complex type to
our emit method.
As you can see, generic interfaces can be a very useful tool for statically typed code.
The primary reason to use interfaces to achieve polymorphism and provide developers to
implement on their own way in future by implementing interface's methods.
https://riptutorial.com/ 53
interface Connector{
doConnect(): boolean;
}
This is connector interface. Now we will implement that for Wifi communication.
Here we have developed our concrete class named WifiConnector that has its own implementation.
This is now type Connector.
Now we are creating our System that has a component Connector. This is called dependency
injection.
constructor(private connector: Connector) this line is very important here. Connector is an interface
and must have doConnect(). As Connector is an interface this class System has much more flexibility.
We can pass any Type which has implemented Connector interface. In future developer achieves
more flexibility. For example, now developer want to add Bluetooth Connection module:
See that Wifi and Bluetooth have its own implementation. There own different way to connect.
However, hence both have implemented Type Connector the are now Type Connector. So that we
can pass any of those to System class as the constructor parameter. This is called polymorphism.
The class System is now not aware of whether it is Bluetooth / Wifi even we can add another
Communication module like Inferade, Bluetooth5 and whatsoever by just implementing Connector
interface.
https://riptutorial.com/ 54
This is called Duck typing. Connector type is now dynamic as doConnect() is just a placeholder and
developer implement this as his/her own.
TypeScript supports interfaces, but the compiler outputs JavaScript, which doesn't. Therefore,
interfaces are effectively lost in the compile step. This is why type checking on interfaces relies on
the shape of the object - meaning whether the object supports the fields and functions on the
interface - and not on whether the interface is actually implemented or not.
interface IKickable {
kick(distance: number): void;
}
class Ball {
kick(distance: number): void {
console.log("Kicked", distance, "meters!");
}
}
let kickable: IKickable = new Ball();
kickable.kick(40);
So even if Ball doesn't explicitly implement IKickable, a Ball instance may be assigned to (and
manipulated as) an IKickable, even when the type is specified.
https://riptutorial.com/ 55
Chapter 14: Mixins
Syntax
• class BeetleGuy implements Climbs, Bulletproof { }
• applyMixins (BeetleGuy, [Climbs, Bulletproof]);
Parameters
Parameter Description
derivedCtor The class that you want to use as the composition class
Remarks
There are three rules to bear in mind with mixins:
• You use the implements keyword, not the extends keyword when you write your composition
class
• You need to have a matching signature to keep the compiler quiet (but it doesn’t need any
real implementation – it will get that from the mixin).
• You need to call applyMixins with the correct arguments.
Examples
Example of Mixins
To create mixins, simply declare lightweight classes that can be used as "behaviours".
class Flies {
fly() {
alert('Is it a bird? Is it a plane?');
}
}
class Climbs {
climb() {
alert('My spider-sense is tingling.');
}
}
class Bulletproof {
deflect() {
alert('My wings are a shield of steel.');
}
https://riptutorial.com/ 56
}
https://riptutorial.com/ 57
Chapter 15: Modules - exporting and
importing
Examples
Hello world module
//hello.ts
export function hello(name: string){
console.log(`Hello ${name}!`);
}
function helloES(name: string){
console.log(`Hola ${name}!`);
}
export {helloES};
export default hello;
If directory contains file named index.ts it can be loaded using only directory name (for index.ts
filename is optional).
//welcome/index.ts
export function welcome(name: string){
console.log(`Welcome ${name}!`);
}
Exporting/Importing declarations
Any declaration (variable, const, function, class, etc.) can be exported from module to be imported
in other module.
https://riptutorial.com/ 58
Named export
// adams.ts
export function hello(name: string){
console.log(`Hello ${name}!`);
}
export const answerToLifeTheUniverseAndEverything = 42;
export const unused = 0;
When importing named exports, you can specify which elements you want to import.
Default export
// dent.ts
const defaultValue = 54;
export default defaultValue;
Bundled import
// adams.ts
export function hello(name: string){
console.log(`Hello ${name}!`);
}
export const answerToLifeTheUniverseAndEverything = 42;
Re-export
//Operator.ts
interface Operator {
eval(a: number, b: number): number;
}
export default Operator;
https://riptutorial.com/ 59
//Add.ts
import Operator from "./Operator";
export class Add implements Operator {
eval(a: number, b: number): number {
return a + b;
}
}
//Mul.ts
import Operator from "./Operator";
export class Mul implements Operator {
eval(a: number, b: number): number {
return a * b;
}
}
//Operators.ts
import {Add} from "./Add";
import {Mul} from "./Mul";
//NamedOperators.ts
export {Add} from "./Add";
export {Mul} from "./Mul";
Default exports can also be exported, but no short syntax is available. Remember, only one
default export per module is possible.
//Calculator.ts
export {Add} from "./Add";
export {Mul} from "./Mul";
import Operator from "./Operator";
//RepackedCalculator.ts
export * from "./Operators";
//FixedCalculator.ts
export * from "./Calculator"
import Operator from "./Calculator";
export class Add implements Operator {
eval(a: number, b: number): number {
return 42;
}
https://riptutorial.com/ 60
}
Usage example
//run.ts
import {Add, Mul} from "./FixedCalculator";
console.log(add.eval(1, 1)); // 42
console.log(mul.eval(3, 4)); // 12
https://riptutorial.com/ 61
Chapter 16: Publish TypeScript definition
files
Examples
Include definition file with library on npm
{
...
"typings": "path/file.d.ts"
...
}
Now when ever that library is imported typescript will load the typings file
https://riptutorial.com/ 62
Chapter 17: Strict null checks
Examples
Strict null checks in action
TypeScript 2.0 adds support for strict null checks. If you set --strictNullChecks when running tsc
(or set this flag in your tsconfig.json), then types no longer permit null:
With a proper guard, the code type checks and runs correctly:
Non-null assertions
The non-null assertion operator, !, allows you to assert that an expression isn't null or undefined
when the TypeScript compiler can't infer that automatically:
https://riptutorial.com/ 63
node.next = {data: 0};
}
}
https://riptutorial.com/ 64
Chapter 18: tsconfig.json
Syntax
• Uses JSON file format
• Can also accept JavaScript style comments
Remarks
Overview
The presence of a tsconfig.json file in a directory indicates that the directory is the root of a
TypeScript project. The tsconfig.json file specifies the root files and the compiler options required
to compile the project.
Using tsconfig.json
• By invoking tsc with no input files, in which case the compiler searches for the tsconfig.json
file starting in the current directory and continuing up the parent directory chain.
• By invoking tsc with no input files and a --project (or just -p) command line option that
specifies the path of a directory containing a tsconfig.json file. When input files are specified
on the command line, tsconfig.json files are
Details
The "compilerOptions" property can be omitted, in which case the compiler’s defaults are used.
See our full list of supported Compiler Options.
If no "files" property is present in a tsconfig.json, the compiler defaults to including all TypeScript
(*.ts or *.tsx) files in the containing directory and subdirectories. When a "files" property is present,
only the specified files are included.
If the "exclude" property is specified, the compiler includes all TypeScript (*.ts or *.tsx) files in the
containing directory and subdirectories except for those files or folders that are excluded.
The "files" property cannot be used in conjunction with the "exclude" property. If both are
specified then the "files" property takes precedence.
Any files that are referenced by those specified in the "files" property are also included. Similarly,
if a file B.ts is referenced by another file A.ts, then B.ts cannot be excluded unless the referencing
file A.ts is also specified in the "exclude" list.
https://riptutorial.com/ 65
A tsconfig.json file is permitted to be completely empty, which compiles all files in the containing
directory and subdirectories with the default compiler options.
Compiler options specified on the command line override those specified in the tsconfig.json file.
Schema
Schema can be found at: http://json.schemastore.org/tsconfig
Examples
Create TypeScript project with tsconfig.json
The presence of a tsconfig.json file indicates that the current directory is the root of a TypeScript
enabled project.
Initializing a TypeScript project, or better put tsconfig.json file, can be done through the following
command:
tsc --init
As of TypeScript v2.3.0 and higher this will create the following tsconfig.json by default:
{
"compilerOptions": {
/* Basic Options */
"target": "es5", /* Specify ECMAScript target version: 'ES3'
(default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'commonjs',
'amd', 'system', 'umd' or 'es2015'. */
// "lib": [], /* Specify library files to be included in the
compilation: */
// "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */
// "jsx": "preserve", /* Specify JSX code generation: 'preserve',
'react-native', or 'react'. */
// "declaration": true, /* Generates corresponding '.d.ts' file. */
// "sourceMap": true, /* Generates corresponding '.map' file. */
// "outFile": "./", /* Concatenate and emit output to single file.
*/
// "outDir": "./", /* Redirect output structure to the directory.
*/
// "rootDir": "./", /* Specify the root directory of input files.
Use to control the output directory structure with --outDir. */
// "removeComments": true, /* Do not emit comments to output. */
// "noEmit": true, /* Do not emit outputs. */
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
// "downlevelIteration": true, /* Provide full support for iterables in 'for-
of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
// "isolatedModules": true, /* Transpile each file as a separate module
(similar to 'ts.transpileModule'). */
https://riptutorial.com/ 66
/* Strict Type-Checking Options */
"strict": true /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Raise error on expressions and declarations
with an implied 'any' type. */
// "strictNullChecks": true, /* Enable strict null checks. */
// "noImplicitThis": true, /* Raise error on 'this' expressions with an
implied 'any' type. */
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict"
for each source file. */
/* Additional Checks */
// "noUnusedLocals": true, /* Report errors on unused locals. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */
// "noImplicitReturns": true, /* Report error when not all code paths in
function return a value. */
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch
statement. */
/* Experimental Options */
// "experimentalDecorators": true, /* Enables experimental support for ES7
decorators. */
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting
type metadata for decorators. */
}
}
Most, if not all, options are generated automatically with only the bare necessities left
uncommented.
Older versions of TypeScript, like for example v2.0.x and lower, would generate a tsconfig.json like
this:
https://riptutorial.com/ 67
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"sourceMap": false
}
}
compileOnSave
Setting a top-level property compileOnSave signals to the IDE to generate all files for a given
tsconfig.json upon saving.
{
"compileOnSave": true,
"compilerOptions": {
...
},
"exclude": [
...
]
}
This feature is available since TypeScript 1.8.4 and onward, but needs to be directly supported by
IDE's. Currently, examples of supported IDE's are:
Comments
A tsconfig.json file can contain both line and block comments, using the same rules as
ECMAScript.
//Leading comment
{
"compilerOptions": {
//this is a line comment
"module": "commonjs", //eol line comment
"target" /*inline block*/ : "es5",
/* This is a
block
comment */
}
}
/* trailing comment */
There are very good configurations to force typings and get more helpful errors which are not
activated by default.
https://riptutorial.com/ 68
{
"compilerOptions": {
"alwaysStrict": true, // Parse in strict mode and emit "use strict" for each source file.
// If you have wrong casing in referenced files e.g. the filename is Global.ts and you
have a /// <reference path="global.ts" /> to reference this file, then this can cause to
unexpected errors. Visite: http://stackoverflow.com/questions/36628612/typescript-transpiler-
casing-issue
"forceConsistentCasingInFileNames": true, // Disallow inconsistently-cased references to
the same file.
"strictNullChecks": true, // The null and undefined values are not in the domain of every
type and are only assignable to themselves and any.
Not enough? If you are a hard coder and want more, then you may be interested to check your
TypeScript files with tslint before compiling it with tsc. Check how to configure tslint for even
stricter code.
preserveConstEnums
This is usually just syntax sugar as the costant enums are inlined in compiled JavaScript.
compiles to
https://riptutorial.com/ 69
var something = 0;
Although the perfomance benefit from inlining, you may prefer to keep enums even if costant (ie:
you may wish readability on development code), to do this you have to set in tsconfig.json the
preserveConstEnums clausole into the compilerOptions to true.
{
"compilerOptions": {
"preserveConstEnums" = true,
...
},
"exclude": [
...
]
}
By this way the previous example would be compiled as any other enums, as shown in following
snippet.
var Tristate;
(function (Tristate) {
Tristate[Tristate["True"] = 0] = "True";
Tristate[Tristate["False"] = 1] = "False";
Tristate[Tristate["Unknown"] = 2] = "Unknown";
})(Tristate || (Tristate = {}));
https://riptutorial.com/ 70
Chapter 19: TSLint - assuring code quality
and consistency
Introduction
TSLint performs static analysis of code and detect errors and potential problems in code.
Examples
Basic tslint.json setup
{
"rules": {
"no-any": true,
"curly": true,
"quotemark": [true, "double"]
}
}
This tslint.json example contains a set of configuration to enforce more typings, catch common
errors or otherwise confusing constructs that are prone to producing bugs and following more the
Coding Guidelines for TypeScript Contributors.
To enforce this rules, include tslint in your build process and check your code before compiling it
with tsc.
{
"rules": {
// TypeScript Specific
"member-access": true, // Requires explicit visibility declarations for class members.
"no-any": true, // Diallows usages of any as a type declaration.
// Functionality
"label-position": true, // Only allows labels in sensible locations.
"no-bitwise": true, // Disallows bitwise operators.
"no-eval": true, // Disallows eval function invocations.
"no-null-keyword": true, // Disallows use of the null keyword literal.
"no-unsafe-finally": true, // Disallows control flow statements, such as return,
continue, break and throws in finally blocks.
"no-var-keyword": true, // Disallows usage of the var keyword.
"radix": true, // Requires the radix parameter to be specified when calling parseInt.
https://riptutorial.com/ 71
"triple-equals": true, // Requires === and !== in place of == and !=.
"use-isnan": true, // Enforces use of the isNaN() function to check for NaN references
instead of a comparison to the NaN constant.
// Style
"class-name": true, // Enforces PascalCased class and interface names.
"interface-name": [ true, "never-prefix" ], // Requires interface names to begin with a
capital ‘I’
"no-angle-bracket-type-assertion": true, // Requires the use of as Type for type
assertions instead of <Type>.
"one-variable-per-declaration": true, // Disallows multiple variable definitions in the
same declaration statement.
"quotemark": [ true, "double", "avoid-escape" ], // Requires double quotes for string
literals.
"semicolon": [ true, "always" ], // Enforces consistent semicolon usage at the end of
every statement.
"variable-name": [true, "ban-keywords", "check-format", "allow-leading-underscore"] //
Checks variable names for various errors. Disallows the use of certain TypeScript keywords
(any, Number, number, String, string, Boolean, boolean, undefined) as variable or parameter.
Allows only camelCased or UPPER_CASED variable names. Allows underscores at the beginning
(only has an effect if “check-format” specified).
}
}
tslint can extend an existing rule set and is shipped with the defaults tslint:recommended and
tslint:latest.
{
"extends": "tslint:recommended"
}
One can then overwrite rules from that preset via rules, e.g. for node developers it made sense to
set no-console to false:
{
"extends": "tslint:recommended",
https://riptutorial.com/ 72
"rules": {
"no-console": false
}
}
Tslint is configured via file tslint.json. To initialize default configuration run command
tslint --init
tslint filename.ts
• tslint-microsoft-contrib
• tslint-eslint-rules
• codelyzer
Yeoman genearator supports all these presets and can be extends also:
• generator-tslint
https://riptutorial.com/ 73
Chapter 20: Typescript basic examples
Remarks
This is a basic example which extends a generic car class and defines a car description method.
Examples
1 basic class inheritance example using extends and super keyword
A generic Car class has some car property and a description method
class Car{
name:string;
engineCapacity:string;
constructor(name:string,engineCapacity:string){
this.name = name;
this.engineCapacity = engineCapacity;
}
describeCar(){
console.log(`${this.name} car comes with ${this.engineCapacity} displacement`);
}
}
HondaCar extends the existing generic car class and adds new property.
constructor(name:string,engineCapacity:string,seatingCapacity:number){
super(name,engineCapacity);
this.seatingCapacity=seatingCapacity;
}
describeHondaCar(){
super.describeCar();
console.log(`this cars comes with seating capacity of ${this.seatingCapacity}`);
}
}
new HondaCar("honda jazz","1200cc",4).describeHondaCar();
2 static class variable example - count how many time method is being
invoked
https://riptutorial.com/ 74
class StaticTest{
static countInstance : number= 0;
constructor(){
StaticTest.countInstance++;
}
}
new StaticTest();
new StaticTest();
console.log(StaticTest.countInstance);
https://riptutorial.com/ 75
Chapter 21: TypeScript Core Types
Syntax
• let variableName: VariableType;
• function functionName(parameterName: VariableType, parameterWithDefault: VariableType
= ParameterDefault, optionalParameter?: VariableType, ...variardicParameter:
VariableType[]): ReturnType { /*...*/};
Examples
Boolean
A boolean represents the most basic datatype in TypeScript, with the purpose of assigning
true/false values.
Number
String
Array
https://riptutorial.com/ 76
An array of values:
Enum
or assign values:
Any
Void
If you have no type at all, commonly used for functions that do not return anything:
Tuple
https://riptutorial.com/ 77
day[2] = 'Saturday'; // valid: [0, 'Saturday']
day[3] = false; // invalid: must be union type of 'number | string'
When you create a function in TypeScript you can specify the data type of the function's
arguments and the data type for the return value
Example:
Here the syntax x: number, y: number means that the function can accept two argumentsx and y
and they can only be numbers and (...): number { means that the return value can only be a
number
Usage:
Note:
or
error TS2322: Type 'string' is not assignable to type 'number' and error TS2322: Type 'number'
is not assignable to type 'string' respectively
Example:
https://riptutorial.com/ 78
Here the syntax name: string means that the function can accept one name argument and this
argument can only be string and (...): string { means that the return value can only be a string
Usage:
String literal types allow you to specify the exact value a string can have.
Together with Type Aliases and Union Types you get a enum-like behavior.
// Error: Argument of type '"rock"' is not assignable to parameter of type "'cat' | "dog" |
"bird". Type '"rock"' is not assignable to type '"bird"'.
// buyPet("rock", "Rocky");
interface Pet {
species: Species;
eat();
sleep();
}
https://riptutorial.com/ 79
}
interface Pet {
species: Species;
name: string;
eat();
walk();
sleep();
}
// Error: Interface 'Rock' incorrectly extends interface 'Pet'. Types of property 'species'
https://riptutorial.com/ 80
are incompatible. Type '"rock"' is not assignable to type '"cat" | "dog" | "bird"'. Type
'"rock"' is not assignable to type '"bird"'.
// interface Rock extends Pet {
// type: "rock";
// }
https://riptutorial.com/ 81
function petIsBird(pet: Pet): pet is Bird {
return pet.species === "bird";
}
if(petIsCat(pet)) {
// pet is now from type Cat (pet: Cat)
pet.eat();
pet.sleep();
} else if(petIsDog(pet)) {
// pet is now from type Dog (pet: Dog)
pet.eat();
pet.walk();
pet.sleep();
} else if(petIsBird(pet)) {
// pet is now from type Bird (pet: Bird)
pet.eat();
pet.sing();
pet.sleep();
} else {
throw "An unknown pet. Did you buy a rock?";
}
}
// Error: Argument of type '"rock"' is not assignable to parameter of type "'cat' | "dog" |
"bird". Type '"rock"' is not assignable to type '"bird"'.
// buyPet("rock", "Rocky");
playWithPet(dog);
// Output: Hey Rocky, let's play.
// Rocky eats.
// Rocky walks.
// Rocky sleeps.
Intersection Types
interface Knife {
cut();
}
https://riptutorial.com/ 82
interface BottleOpener{
openBottle();
}
interface Screwdriver{
turnScrew();
}
tool.cut();
tool.openBottle();
tool.turnScrew();
}
const Enum
A const Enum is the same as a normal Enum. Except that no Object is generated at compile time.
Instead, the literal values are substituted where the const Enum is used.
// Typescript: A const Enum can be defined like a normal Enum (with start value, specifig
values, etc.)
const enum NinjaActivity {
Espionage,
Sabotage,
Assassination
}
// Javascript: Then only the number of the value is compiled into the code
// var myFavoriteNinjaActivity = 0 /* Espionage */;
// console.log(myFavoritePirateActivity); // 0
// Javascript: Just the number and in a comment the name of the value
// console.log(1 /* "Sabotage" */); // 1
https://riptutorial.com/ 83
Fencing
}
https://riptutorial.com/ 84
Chapter 22: TypeScript with AngularJS
Parameters
Name Description
Remarks
While doing the directive in TypeScript, keep in mind, that power of this language of custom type
and interfaces that you can create. This is extremely helpfull when developing huge applications.
Code completion supported by many IDE will show you the possible value by corresponding type
you are working with, so there is far more less that should be kept in mind (comparing to
VanillaJS).
Examples
Directive
interface IMyDirectiveController {
// specify exposed controller methods and properties here
getUrl(): string;
}
/*
* Outer injections, for run once controll.
* For example we have all templates in one value, and we wan't to use it.
*/
https://riptutorial.com/ 85
export function myDirective(templatesUrl: ITemplates): ng.IDirective {
return {
controller: MyDirectiveController,
controllerAs: "vm",
},
replace: true,
require: "ngModel",
restrict: "A",
templateUrl: templatesUrl.myDirective,
};
}
myDirective.$inject = [
Templates.prototype.slug,
];
// Using slug naming across the projects simplifies change of the directive name
myDirective.prototype.slug = "myDirective";
// You can place this in some bootstrap file, or have them at the same file
angular.module("myApp").
directive(myDirective.prototype.slug, myDirective);
Simple example
},
replace: true,
require: "ngModel",
restrict: "A",
templateUrl: templatesUrl.myDirective,
};
}
// Using slug naming across the projects simplifies change of the directive name
myDirective.prototype.slug = "myDirective";
// You can place this in some bootstrap file, or have them at the same file
angular.module("myApp").
https://riptutorial.com/ 86
directive(myDirective.prototype.slug, [
Templates.prototype.slug,
myDirective
]);
Component
For an easier transition to Angular 2, it's recommended to use Component, available since Angular
1.5.8
myModule.ts
angular
.module("myModule", [])
.component("myModuleComponent", new MyModuleComponent())
.service("myModuleService", MyModuleService);
components/myModuleComponent.ts
templates/myModuleComponent.html
<div class="my-module-component">
{{$ctrl.someContent}}
</div>
controller/MyModuleController.ts
https://riptutorial.com/ 87
}
}
services/MyModuleService.ts
constructor() {
}
somewhere.html
<my-module-component></my-module-component>
https://riptutorial.com/ 88
Chapter 23: TypeScript with SystemJS
Examples
Hello World in the browser with SystemJS
NOTE: this will install typescript 2.0.0 compiler which is not released yet.
<!doctype html>
<html>
<head>
<title>Hello World in TypeScript</title>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="config.js"></script>
<script>
window.addEventListener('load', function() {
System.import('./hello.ts').then(function(hello) {
document.body.innerHTML = hello.greeter('World');
});
});
</script>
</head>
<body>
</body>
</html>
System.config({
packages: {
"plugin-typescript": {
"main": "plugin.js"
},
https://riptutorial.com/ 89
"typescript": {
"main": "lib/typescript.js",
"meta": {
"lib/typescript.js": {
"exports": "ts"
}
}
}
},
map: {
"plugin-typescript": "node_modules/plugin-typescript/lib/",
/* NOTE: this is for npm 3 (node 6) */
/* for npm 2, typescript path will be */
/* node_modules/plugin-typescript/node_modules/typescript */
"typescript": "node_modules/typescript/"
},
transpiler: "plugin-typescript",
meta: {
"./hello.ts": {
format: "esm",
loader: "plugin-typescript"
}
},
typescriptOptions: {
typeCheck: 'strict'
}
});
NOTE: if you don't want type checking, remove loader: "plugin-typescript" and typescriptOptions
from config.js. Also note that it will never check javascript code, in particular code in the <script>
tag in html example.
Test it
node build.js
Use it in production
https://riptutorial.com/ 90
Just load hello.js with a script tag before first use
hello-production.html file:
<!doctype html>
<html>
<head>
<title>Hello World in TypeScript</title>
<script src="node_modules/systemjs/dist/system.src.js"></script>
<script src="config.js"></script>
<script src="hello.js"></script>
<script>
window.addEventListener('load', function() {
System.import('./hello.ts').then(function(hello) {
document.body.innerHTML = hello.greeter('World');
});
});
</script>
</head>
<body>
</body>
</html>
https://riptutorial.com/ 91
Chapter 24: Typescript-installing-typescript-
and-running-the-typescript-compiler-tsc
Introduction
How to install TypeScript and run the TypeScript compiler against a .ts file from the command line.
Examples
Steps.
tsc -v
https://riptutorial.com/ 92
See the result in compiled javascript of written typescript code.
Thank you.
https://riptutorial.com/ 93
Chapter 25: Unit Testing
Examples
Alsatian
Alsatian is a unit testing framework written in TypeScript. It allows for usage of Test Cases, and
outputs TAP-compliant markup.
export SomeModuleTests {
@Test()
public statusShouldBeTrueByDefault() {
let instance = new SomeModule();
Expect(instance.status).toBe(true);
}
Expect(instance.name).toBe(null);
}
@TestCase("first name")
@TestCase("apples")
public shouldSetNameCorrectly(name: string) {
let instance = new SomeModule();
instance.setName(name);
Expect(instance.name).toBe(name);
}
chai-immutable plugin
https://riptutorial.com/ 94
npm install --save-dev chai chai-immutable ts-node
chai.use(chaiImmutable);
expect(Set.of(1,2,3)).to.include(2);
expect(Set.of(1,2,3)).to.include(5);
})
})
tape
To use tape with Typescript you need to install ts-node as global package, to do this run command
//math.test.ts
import * as test from "tape";
t.end();
});
https://riptutorial.com/ 95
To execute test run command
TAP version 13
# Math test
ok 1 should be equal
ok 2 should be truthy
1..2
# tests 2
# pass 2
# ok
You can run multiple test files at once using path wildcards. To execute all Typescript tests in
tests directory run command
jest (ts-jest)
jest is painless JavaScript testing framework by Facebook, with ts-jest can be used to test
TypeScript code.
To make jest work with TypeScript you need to add configuration to package.json
//package.json
{
...
"jest": {
"transform": {
".(ts|tsx)": "<rootDir>/node_modules/ts-jest/preprocessor.js"
},
"testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
"moduleFileExtensions": ["ts", "tsx", "js"]
}
https://riptutorial.com/ 96
}
//fizzBuzz.ts
export function fizzBuzz(n: number): string {
let output = "";
for (let i = 1; i <= n; i++) {
if (i % 5 && i % 3) {
output += i + ' ';
}
if (i % 3 === 0) {
output += 'Fizz ';
}
if (i % 5 === 0) {
output += 'Buzz ';
}
}
return output;
}
//FizzBuzz.test.ts
/// <reference types="jest" />
jest
PASS ./fizzBuzz.test.ts
✓ FizzBuzz test (3ms)
Code coverage
jest supports generation of code coverage reports.
To use code coverage with TypeScript you need to add another configuration line to package.json.
https://riptutorial.com/ 97
{
...
"jest": {
...
"testResultsProcessor": "<rootDir>/node_modules/ts-jest/coverageprocessor.js"
}
}
jest --coverage
PASS ./fizzBuzz.test.ts
✓ FizzBuzz test (3ms)
-------------|----------|----------|----------|----------|----------------|
File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines |
-------------|----------|----------|----------|----------|----------------|
All files | 92.31 | 87.5 | 100 | 91.67 | |
fizzBuzz.ts | 92.31 | 87.5 | 100 | 91.67 | 13 |
-------------|----------|----------|----------|----------|----------------|
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 1.857s
Ran all test suites.
jest also created folder coverage which contains coverage report in various formats, including user
friendly html report in coverage/lcov-report/index.html
https://riptutorial.com/ 98
Read Unit Testing online: https://riptutorial.com/typescript/topic/7456/unit-testing
https://riptutorial.com/ 99
Chapter 26: User-defined Type Guards
Syntax
• typeof x === "type name"
• x instanceof TypeName
• function(foo: any): foo is TypeName { /* code returning boolean */ }
Remarks
Using type annotations in TypeScript constrains the possible types your code will need to deal
with, but it is still common to need to take different code paths based on the runtime type of a
variable.
Type guards let you write code that discriminates based on the runtime type of a variable, while
remaining strongly typed and avoiding casts (also known as type assertions).
Examples
Using instanceof
class Pet { }
class Dog extends Pet {
bark() {
console.log("woof");
}
}
class Cat extends Pet {
purr() {
console.log("meow");
}
}
example(new Dog());
https://riptutorial.com/ 100
example(new Cat());
prints
woof
meom
to the console.
Using typeof
typeofis used when you need to distinguish between types number, string, boolean, and symbol.
Other string constants will not error, but won't be used to narrow types either.
Unlike instanceof, typeof will work with a variable of any type. In the example below, foo could be
typed as number | string without issue.
example(23);
example("foo");
prints
123
not a number: foo
You can declare functions that serve as type guards using any logic you'd like.
If the function returns true, TypeScript will narrow the type to DesiredType in any block guarded by a
call to the function.
https://riptutorial.com/ 101
For example (try it):
A guard's function type predicate (the foo is Bar in the function return type position) is used at
compile time to narrow types, the function body is used at runtime. The type predicate and
function must agree, or your code won't work.
Type guard functions don't have to use typeof or instanceof, they can use more complicated logic.
For example, this code determines if you've got a jQuery object by checking for it's version string.
function example(foo) {
if (isJQuery(foo)) {
// foo is typed JQuery here
foo.eq(0);
}
}
https://riptutorial.com/ 102
Chapter 27: Using Typescript with React (JS
& native)
Examples
ReactJS component written in Typescript
You can use ReactJS's components easily in TypeScript. Just rename the 'jsx' file extension to
'tsx':
//helloMessage.tsx:
var HelloMessage = React.createClass({
render: function() {
return <div>Hello {this.props.name}</div>;
}
});
But in order to make full use of TypeScript's main feature (static type checking) you must do a
couple things:
//helloMessage.tsx:
class HelloMessage extends React.Component {
render() {
return <div>Hello {this.props.name}</div>;
}
}
interface Props {
name:string;
optionalParam?:number;
}
interface State {
//empty in our case
}
https://riptutorial.com/ 103
// TypeScript will allow you to create without the optional parameter
ReactDOM.render(<HelloMessage name="Sebastian" />, mountNode);
// But it does check if you pass in an optional parameter of the wrong type
ReactDOM.render(<HelloMessage name="Sebastian" optionalParam='foo' />, mountNode);
Now TypeScript will display an error if the programmer forgets to pass props. Or if trying to pass in
props that are not defined in the interface.
Linking TypeScript allows ts-loader to use your global installation of TypeScript instead
of needing a separate local copy typescript doc
{
"compilerOptions": {
"sourceMap": true,
"noImplicitAny": true,
"module": "commonjs",
"target": "es5",
"jsx": "react"
}
}
module.exports = {
entry: "<path to entry point>",// for example ./src/helloMessage.tsx
output: {
filename: "<path to bundle file>", // for example ./dist/bundle.js
},
https://riptutorial.com/ 104
resolve: {
// Add '.ts' and '.tsx' as resolvable extensions.
extensions: ["", ".webpack.js", ".web.js", ".ts", ".tsx", ".js"]
},
module: {
loaders: [
// All files with a '.ts' or '.tsx' extension will be handled by 'ts-loader'.
{test: /\.tsx?$/, loader: "ts-loader"}
],
preLoaders: [
// All output '.js' files will have any sourcemaps re-processed by 'source-map-
loader'.
{test: /\.js$/, loader: "source-map-loader"}
]
},
// When importing a module whose path matches one of the following, just
// assume a corresponding global variable exists and use that instead.
// This is important because it allows us to avoid bundling all of our
// dependencies, which allows browsers to cache those libraries between builds.
externals: {
"react": "React",
"react-dom": "ReactDOM"
},
};
https://riptutorial.com/ 105
Chapter 28: Using Typescript with RequireJS
Introduction
RequireJS is a JavaScript file and module loader. It is optimized for in-browser use, but it can be
used in other JavaScript environments, like Rhino and Node. Using a modular script loader like
RequireJS will improve the speed and quality of your code.
Using TypeScript with RequireJS requires configuration of tsconfig.json, and including an snippet
in any HTML file. Compiler will traduce imports from the syntax of TypeScript to RequireJS' format.
Examples
HTML example using requireJS CDN to include an already compiled
TypeScript file.
<body onload="__init();">
...
<script src="http://requirejs.org/docs/release/2.3.2/comments/require.js"></script>
<script>
function __init() {
require(["view/index.js"]);
}
</script>
</body>
{
"module": "amd", // Using AMD module code generator which works with requireJS
"rootDir": "./src", // Change this to your source folder
"outDir": "./view",
...
}
https://riptutorial.com/ 106
Chapter 29: Using TypeScript with webpack
Examples
webpack.config.js
tsconfig.json
{
"compilerOptions": {
"sourceMap": true,
"noImplicitAny": true,
"module": "commonjs",
"target": "es5",
"jsx": "react" // if you want to use react jsx
}
}
module.exports = {
entry: "./src/index.ts",
output: {
filename: "./dist/bundle.js",
},
resolve: {
// Add '.ts' and '.tsx' as resolvable extensions.
extensions: ["", ".webpack.js", ".web.js", ".ts", ".tsx", ".js"]
},
module: {
loaders: [
// All files with a '.ts' or '.tsx' extension will be handled by 'ts-loader'.
{test: /\.tsx?$/, loader: "ts-loader"}
],
preLoaders: [
// All output '.js' files will have any sourcemaps re-processed by 'source-map-
loader'.
{test: /\.js$/, loader: "source-map-loader"}
]
},
/*****************************
* If you want to use react *
****************************/
// When importing a module whose path matches one of the following, just
// assume a corresponding global variable exists and use that instead.
// This is important because it allows us to avoid bundling all of our
// dependencies, which allows browsers to cache those libraries between builds.
https://riptutorial.com/ 107
// externals: {
// "react": "React",
// "react-dom": "ReactDOM"
// },
};
https://riptutorial.com/ 108
Chapter 30: Why and when to use TypeScript
Introduction
If you find the arguments for type systems persuasive in general, then you'll be happy with
TypeScript.
It brings many of the advantages of type system (safety, readability, improved tooling) to the
JavaScript ecosystem. It also suffers from some of the drawbacks of type systems (added
complexity and incompleteness).
Remarks
The merits of typed vs. untyped languages have been debated for decades. Arguments for static
types include:
1. Safety: type systems allow many errors to be caught early, without running the code.
TypeScript can be configured to allow fewer programming errors
2. Readability: explicit types make code easier for humans to understand. As Fred Brooks
wrote, "Show me your flowcharts and conceal your tables, and I shall continue to be
mystified. Show me your tables, and I won’t usually need your flowcharts; they’ll be obvious."
3. Tooling: type systems make code easier for computers to understand. This allows tools like
IDEs and linters to be more powerful.
4. Performance: type systems make code run faster by reducing the need for runtime type
checking.
1. Added complexity: type systems can be more complex than the language runtime that they
describe. Higher order functions can be easy to implement correctly but difficult to type.
Dealing with type definitions creates additional barriers to using external libraries.
2. Added verbosity: type annotations can add boilerplate to your code, making the underlying
logic harder to follow.
3. Slower iteration: by introducing a build step, TypeScript slows down the edit/save/reload
cycle.
4. Incompleteness: A type system cannot be both sound and complete. There are correct
programs which TypeScript does not allow. And programs which TypeScript accepts can still
contain bugs. A type system doesn't alleviate the need for testing. If you use TypeScript, you
may have to wait longer to use new ECMAScript language features.
1. Added complexity. If typing part of a program is too difficult, TypeScript can be largely
https://riptutorial.com/ 109
disabled using an opaque any type. The same is true for external modules.
2. Added verbosity. This can partially be addressed through type aliases and TypeScript's
ability to infer types. Writing clear code is as much an art as a science: remove too many
type annotations and the code may no longer be clear to human readers.
3. Slower iteration: A build step is relatively common in modern JS development and
TypeScript already integrates with most build tools. And if TypeScript catches an error early,
it can save you an entire iteration cycle!
4. Incompleteness. While this problem cannot be completely solved, TypeScript has been able
to capture more and more expressive JavaScript patterns over time. Recent examples
include the addition of mapped types in TypeScript 2.1 and mixins in 2.2.
The arguments for and against type systems in general apply equally well to TypeScript. Using
TypeScript increases the overhead to starting a new project. But over time, as the project
increases in size and gains more contributors, the hope is that the pros of using it (safety,
readability, tooling) become stronger and outweigh the cons. This is reflected in TypeScript's
motto: "JavaScript that scales."
Examples
Safety
Readability
You'll never forget whether String.prototype.slice takes (start, stop) or (start, length) again!
Tooling
TypeScript allows editors to perform automated refactors which are aware of the rules of the
languages.
https://riptutorial.com/ 110
Here, for instance, Visual Studio Code is able to rename references to the inner foo without
altering the outer foo. This would be difficult to do with a simple find/replace.
https://riptutorial.com/ 111
Credits
S.
Chapters Contributors
No
Configure typescript
5 project to compile all Rahul
files in typescript.
6 Debugging Peopleware
How to use a
javascript library
10 Bruno Krebs, Kevin Montrose
without a type
definition file
Integrating with Build Alex Filatov, BrunoLM, Dan, dublicator, John Ruddell, mleko,
12
Tools Protectator, smnbbrv, void
https://riptutorial.com/ 112
, Slava Shpitalny, Sunnyok
14 Mixins Fenton
Modules - exporting
15 mleko
and importing
Publish TypeScript
16 2426021684
definition files
TSLint - assuring
19 code quality and Alex Filatov, James Monger, k0pernikus, Magu, mleko
consistency
Typescript basic
20 vashishth
examples
TypeScript Core
21 dublicator, Fenton, Fylax, Magu, Mikhail, Moriarty, RationalDev
Types
TypeScript with
22 Chic, Roman M. Koss, Stefan Rein
AngularJS
TypeScript with
23 artem
SystemJS
Typescript-installing-
typescript-and-
24 running-the- Rahul
typescript-compiler-
tsc
User-defined Type
26 Kevin Montrose
Guards
Using Typescript
Aleh Kashnikau, irakli khitarishvili, islandman93, Rajab Shakirov
27 with React (JS &
, tBX
native)
Using Typescript
28 lilezek
with RequireJS
https://riptutorial.com/ 113
with webpack
https://riptutorial.com/ 114