For collections, there are typed arrays and generic arrays
let list: number[] = [1, 2, 3];
// Or, using the generic array type
let list: Array<number> = [1, 2, 3];
For enumerations
enum Color { Red, Yellow, Green };
let c: Color = Color.Green;
if (c === Color.Green) {
console.log('Lets go!');
}
Lastly, void is used in the special case of a function returning nothing.
function bigHorribleAlert(): void {
alert('I'm a little annoying box!');
}
Functions
Functions are first class citizens, support the lambda 'fat arrow' syntax and use type inference.
The following are equivalent, the same signature will be inferred by the compiler, and same JavaScript will be emitted
Regular function
// Function Declaration
function f1(i: number): number {
return i * i;
}
// Function Expression let f1 = function (i: number): number { return i * i; }
Return type inferred
let f2 = function (i: number) {
return i * i;
}
'Fat arrow' syntax
let f3 = (i: number): number => {
return i * i;
}
'Fat arrow' syntax with return type inferred
let f4 = (i: number) => { return i * i; }
'Fat arrow' syntax with return type inferred, braceless means no return keyword needed.
let f5 = (i: number) => i * i;
var, let, and const
Declaring a variable using the above keywords:
Both type and initial value.
var width:number = 100;
let height:number = 200;
const key:string = 'abc123';
Without type, but with an initial value.
var width = 100;
let height = 200;
const key = 'abc123';
Only the type.
var width: number;
let height: number;
// const does not support without initial value
Without type and initial value.
var width;
let height;
// const does not support without initial value
function someFn() {
if (true) {
// defined locally
// its scope ends where curly braces ends
var local = 1000;
console.log(local); //ok
}
console.log(local); //ok
function nested() {
console.log(local); //ok
}
}
console.log(local); //error
let and const are Block Scoped
function someFn() {
if (true) {
// defined locally
// its scope ends where curly braces ends
let local = 1000;
console.log(local); // ok
}
console.log(local); //error
function nested() {
console.log(local); //error
}
}
console.log(local); //error
Interfaces
Interfaces are structural, anything that has the properties is compliant with the interface.
interface Person {
name: string;
// Optional properties, marked with a '?'
age?: number;
// And of course functions
move(): void;
}
Object that implements the Person interface can be treated as a Person since it has the name and move properties
let p: Person = {
name: 'Bobby',
move: () => { }
};
let validPerson: Person = {
name: 'Bobby',
age: 42, // optional property
move: () => { }
};
Object below is not a person because age is not a number and there is no move function.
let invalidPerson: Person = {
name: 'Bobby',
age: true
};
Only the parameters' types are important, names are not important.
let mySearch: SearchFunc;
mySearch = function (src: string, sub: string) {
return src.search(sub) != -1;
}
Classes
Class members are public by default
class Point {
// Properties
x: number;
/* Constructor - the public/private keywords
* in this context will generate the boiler
* plate code for the property and the
* initialization in the constructor.
*
* In this example,
* 'y' will be defined just like 'x' is,
* but with less code
*
* Default values are also supported
*/
constructor(x: number, public y: number = 0) {
this.x = x;
}
// Functions
dist() {
return Math.sqrt(this.x * this.x + this.y * this.y);
}
// Static members
static origin = new Point(0, 0);
}
let p1 = new Point(10, 20);
let p2 = new Point(25); //y will be 0
Classes can be explicitly marked as implementing an interface. Any missing properties will then cause an error at compile-time.
class PointPerson implements Person {
name: string;
move() {}
}
Class inheritance
class Point3D extends Point {
constructor(x: number, y: number, public z: number = 0) {
// Explicit call to the super class constructor
// is mandatory
super(x, y);
}
// Override
dist() {
let d = super.dist();
return Math.sqrt(d() * d() + this.z * this.z);
}
}
Generics
Classes
class Tuple<T1, T2> {
constructor(public item1: T1, public item2: T2) {}
}
Interfaces
interface Pair<T> {
item1: T;
item2: T;
}
And functions
let pairToTuple = function <T>(p: Pair<T>) {
return new Tuple(p.item1, p.item2);
};
let tuple = pairToTuple({
item1: 'hello',
item2: 'world'
});
Template strings
Template Strings: strings that use backticks (`).
String Interpolation with Template Strings
let name = 'Tyrone';
let greeting = `Hi ${name}, how are you?`
Multiline Strings with Template Strings
let multiline = `This is an example
of a multiline string`;
Iterators
for..of statement. Iterate over the list of values on the object being iterated.
let arrayOfAnyType = [1, 'string', false];
for (const val of arrayOfAnyType) { console.log(val); // 1, 'string', false }
let list = [4, 5, 6];
for (const i of list) {
console.log(i); // 4, 5, 6
}
let arrayOfAnyType = [1, 'string', false];
for (const val of arrayOfAnyType) {
console.log(val); // 1, 'string', false
}
let list = [4, 5, 6];
for (const i of list) { console.log(i); // 4, 5, 6 }
for..in statement. Iterate over the list of keys on the object being iterated.
for (const i in list) {
console.log(i); // 0, 1, 2
}