Overview

const a: any = null;

let b: boolean = true;
let c: number = 10;
let d: string = "Test";

// Arrays:
let e: int[] = [1, 2, 3];
let f: string[] = ["a", "b", "c"];

// Tupple (Array with fixed number of elements):
let g: [string, number] = ["hello", 10];
console.log(g[0]);

// Union:
string | null | undefined

// Function returning "never" must have unreachable end point.
function error(message: string): never {
    throw new Error(message);
}

// Enums:
enum Color {
	Gray, // 0
	Red, // 1
	Green = 100, // 100
	Blue, // 101
	Yellow = 2 // 2
}
let h: Color = Color.Green;

// Type Assertions (Casting)
let len: number = (input as string).length;
// This approach is not allowed in JSX.
// let len: number = (<string> input).length;

// Type Aliases
type Name = string | string[];

interface Item {
    id: string;
    name: string;
}

// Dictionary:
interface MyInterface {
    data: Record<string, Item>;
}

Type Extraction

interface Building {
  room: {
    door: string,
    walls: string[],
  };
}

type Walls = Building['room']['walls']; // string[]

Functions

// Arrow functions.
function add(a: number, b: number): number => a + b;

// Optional parameters with ?
function buildName(firstName: string, lastName?: string) {
	return lastName 
		? firstName + " " + lastName
		: firstName;
}

// Default value.
function buildName(firstName: string, lastName = "Smith") => firstName + " " + lastName;

// Rest Parameters:
function buildName(firstName: string, ...restOfName: string[]) => firstName + " " + restOfName.join(" ");
let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");

Interfaces

// Inline:
****function printLabel(options: { label: string }) {
  console.log(options.label);
}

function getUser(): { name: string; age?: number } {
	return {
		name: "Saeid",
		age: 100
	}
}

// Explicit:
interface LabelOptions {
  label: string
}
function printLabel(options: LabelOptions) { ... }

interface User {
  readonly name: string, // Readonly property.
  age?: number // Optional property.
}
function getUser(): User => {
	name: "Saeid"
}

// Interface with function type:
interface SearchFunc {
    (source: string, subString: string): boolean;
}
let mySearch: SearchFunc = function(source: string, subString: string) {
    return source.search(subString) > -1;
}

// Indexable Types:
interface StringArray {
    [index: number]: string;
}
let myArray: StringArray = ["Bob", "Fred"];

// Extending Interfaces:
interface Shape {
    color: string;
}
interface Square extends Shape {
    sideLength: number;
}

Interfaces Extending Classes

Classes

class Point {
	// Members are public by default.
	public x: number;
	y: number;
	static instances = 0;
	// Private members cannot be accessed from outside of its containing class.
	private z: boolean;
	// The protected modifier acts much like the private modifier with the exception 
	// that members declared protected can also be accessed within deriving classes.
	protected p: string;
	// Readonly members must be initialized at their declaration or in the constructor.
	readonly h: number;

  constructor(x: number, y: number) {
    this.x = x
    this.y = y
  }
}

interface ClockInterface {
    currentTime: Date;
    setTime(d: Date): void;
}
interface ClockConstructor {
    new (hour: number, minute: number);
}
class Clock implements ClockInterface, ClockConstructor {
    currentTime: Date = new Date();
    setTime(d: Date) {
        this.currentTime = d;
    }
    constructor(h: number, m: number) { }
}

// Inheritance:
class Point {...}
class Point3D extends Point {...}
interface Colored {...}
class Pixel extends Point implements Colored {...}

Generics