Intro to TypeScript
Installation
Some useful guides & examples:
Basic Types
// boolean
let iAmBoolean: boolean = true;
// number
let iAmNumber: number = 1;
// string
let iAmString: string = 'Hello';
// Array
const iAmArray: number[] = [1, 2, 3];
const iAmArrayToo: Array<number> = [1, 2, 3];
// enum
enum Color {Red, Green, Blue};
// this will be 0, the index of the element
let colorIndex: Color = Color.Red;
// this will be 'Red', the string from the enum
let colorName: string = Color[1];
// any
let iAmAnything: any = 1;
iAmAnything = 'yes, still me';
// undefined & null
let iAmUndefined: undefined = undefined;
let iAmNull: null = null;
// object
const iAmAnObject: object = {};
// Type assertions
let iAmSomeVariable: any = 'i am actually a string';
let strLength: number = (<string>iAmSomeVariable).length;
let theSameStrLength: number = (iAmSomeVariable as string).length;
// More info here:
// https://www.typescriptlang.org/docs/handbook/basic-types.htmlFunctions
// void
function iAmAVoidFunction (): void {
// do not return anything
};
// number
function doubleMe (a: number): number {
return a * 2;
}
let x: number = doubleMe(1);
// never
function error (): never {
// do not finish executing
while(true) {}
// or throw an error
throw new Error('leave me alone');
};
// optimal, default and rest paramters
function buildName(firstName: string, lastName: string, ...restOfName: string[]) {
return `${firstName} ${lastName} ${restOfName.join(' ')}`;
}
buildName('John', 'Smith'); // ok
buildName('John', 'Smith', 'Jr.'); // ok
// buildName('John'); // too little parameters, we can fix it by making a parameter optionalEnums
// Numeric enums
enum Direction {
Up = 1,
Down, // 2
Left, // 3
Right, // 4
};
let up = Direction.Up; // this will be 1
// String enums
enum DirectionNames = {
Up = 'UP',
Down = 'DOWN',
Left = 'LEFT',
Right = 'RIGHT'
};
let left = DirectionNames.Left; // this will be 'LEFT'
// Heterogeneous enums
enum BooleanLikeHeterogeneousEnum {
No = 0,
Yes = 'YES'
};Classes and Interfaces
// Object types
interface Person {
name: string;
age: number;
// this is optional
gender?: ('male' | 'female');
// this is readonly
readonly nationalId: number;
};
const iAmAPerson: Person = {name: 'Me', age: 20, nationalId: 12345};
const iAmAGuy: Person = {name: 'Me', age: 20, gender: 'male', nationalId: 12345};
const iAmAGirl: Person = {name: 'Me', age: 20, gender: 'female', nationalId: 12345};
// TypeScript will complain about this:
// iAmAPerson.nationalId = 456789;
// this is a readonly array
const a: number[] = [1, 2, 3];
const b: ReadonlyArray<number> = a;
// TypeScript will complain about this:
// b.push(4);
// Function types
interface PrintPersonFunc {
(name: string, age: number): void
};
const printPerson: PrintPersonFunc = (name: string, age: number) => {
console.log(`Hello, my name is ${name} and I am ${age} years old.`);
};
printPerson('Joe', 30);
// Classes
interface ClockInterface {
currentTime: Date;
setTime(d: Date): void;
};
class Clock implements ClockInterface {
currentTime: Date;
setTime (d: Date) {
this.currentTime = d;
}
};
// interfaces can be extended
interface AnimalInterface {
species: string;
};
interface DogInterface extends AnimalInterface {
bark(): void
};
class Animal implements AnimalInterface {
species: string;
}
class Dog implements DogInterface {
species: string;
bark: () => {}
}
// More info here:
// https://www.typescriptlang.org/docs/handbook/interfaces.htmlGenerics
// this gets a number as an input and returns a number
function iAcceptANumberAndReturnANumber (arg: number): number {
return arg;
};
// this gets any input and returns any type of output
function iAcceptAnythingAndReturnAnything (arg: any): any {
return arg;
};
// this gets any input and returns an output of the same type
function iAcceptAnythtingAndReturnTheSameType<T> (arg: T): T {
return arg;
};Advanced types
// Intersection types
interface StudentInterface {
id: string;
age: number;
};
interface WorkerInterface {
companyId: string;
};
type StudentWhoWorks = StudentInterface & WorkerInterface;
// actually it's not an intersection like in maths,
// the intersected type gets all the properties from the other 2 types
const iAmAStudentWhoWorks: StudentWhoWorks = {
id: '1',
age: 20,
companyId: '1'
};
// Union types
let iAmANumberOrString: number | string = 1;
iAmANumberOrString = 'a';
type StudentOrWorker = StudentInterface | WorkerInterface;
// by union TS means that a variable can be of any of the types mentioned
const iAmAStudentWhoDoesNotWork: StudentOrWorker = {
id: '1',
age: 20
};
const iAmAWorker: StudentOrWorker = {
companyId: '123'
};Tuples
// This defines the order of the element types
let iAmAnArrayWithAStringAndANumber: [string, number];
iAmAnArrayWithAStringAndANumber = ['a', 1]; // ok
// iAmAnArrayWithAStringAndANumber = [1, 'a']; // not ok
iAmAnArrayWithAStringAndANumber.push(2); // ok
// iAmAnArrayWithAStringAndANumber.push(false)
// not ok, needs to be number | string
Type inference
// this will be a number
let n = 3;
n = 1; // ok
// n = 'a'; // not ok, the type was assigned as a number already
// the elements on this array will be either numbers either boolean
let arr = [0, 1, true];
arr.push(2); // ok
arr.push(false); //ok
// arr.push('a');
// not ok, the type of the elements needs to be number or boolean
// the mouseEvent has automatically assigned the type MouseEvent
window.onmousedown = function(mouseEvent) {
// console.log(mouseEvent.clickTime);
// not ok, MouseEvent doesn't have the clickTime property
};TypeScript vs Flow
- TypeScript implements a type checker and a transpiler (but no polyfill, Babel needs to be used for polyfills)
- Flow implements only a type checker (it needs to be integrated with Babel)
- TypeScript works better with Angular, Flow works better with React, but they can be used the other way around too
- TypeScript is more popular than Flow: https://2018.stateofjs.com/javascript-flavors/conclusion/
Thank you!
Intro to TypeScript
By alininayeh
Intro to TypeScript
- 216