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");
// 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
- When an interface type extends a class type it inherits the members of the class but not their implementations.
- Interfaces inherit even the private and protected members of a base class.
- This means that when you create an interface that extends a class with private or protected members, that interface type can only be implemented by that class or a subclass of it.
- This is useful when you have a large inheritance hierarchy, but want to specify that your code works with only subclasses that have certain properties.
- The subclasses don’t have to be related besides inheriting from the base class.
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 {...}
- Abstract classes are base classes from which other classes may be derived.
- They may not be instantiated directly.
- Unlike an interface, an abstract class may contain implementation details for its members.