Get Started with Typescript

1 Get Started with Typescript

Any large and good apps written in Javascript will be eventually written in Typescript.

1-1 Types of Languages

  • Dynamically Typed Language

    • Type check will be done at runtime
    • No need to assign data type to variables, very flexible
    • e.g. Python, Javascript etc.
    • Note Python has introduced the type hint
  • Statically Typed Language

    • Type check happens during the compile phase
    • Need to declare the data type for variables
    • e.g. C++, Java

1-2 What is Typescript

  • A Javascript superset
  • Javascript that scales
  • A Typed language
  • Supporting ES6 through ES10 even ESnext
  • Compatible with modern browsers, OS, servers
  • Open Source

1-3 Why use Typescript

  • Easy to understand
  • Easy to prevent errors
  • More efficient
  • Completely Compatible with JS
  • More and more popular frameworks are written in Typescript now
  • Cons
    • Learning curve
    • Additional dev costs in the near term

1-4 Install Typescript

  • Install Typescript
script
npm install -g typescript
  • Check version
script
tsc -v

Version 3.8.3
  • Install a certain version
script
npm i -g typescript@3.7.2

Check version again

script
Version 3.7.2

1-5 Hello World in Typescript

  • Create a file hello.ts
  • Edit the file
const hello = (name: string) => {
return `hello ${name}`
}

hello('World')
  • Compile the file
script
tsc hello.ts

Then the system will generate a js file

var hello = function (name) {
return "hello " + name;
};
hello('World');
  • Error during compiling
const hello = (name: string) => {
return `hello ${name}`
}

hello('World')
hello(42)

System will report error if compiling

script
helloword.ts:6:7 - error TS2345: Argument of type '20' is not assignable to parameter of type 'string'.

6 hello(20)
~~
Found 1 error.

2 Data Type

2-1 Data types in Javascript

There are 7 primitive data types:
- Boolean
- Null
- Undefined
- Number
- BigInt (ES6)
- String
- Symbol (ES6)
And Object

2-2 Basic Data Types

Some basic data types:

let isDone: boolean = false

let age: number = 20
let binNumber: number = 0b1111

let firstN: string = "Isaac"
let msg: string = `Hello ${firstN}, age is ${age}`

let udf: undefined = undefined
let n: null = null
```
note `undefine` and `null` are sub-type for `number`, `string` and `boolean`, we can define a `number` type `undefined`

Below is valid:

```typescript
let myNum: number = undefined

2-3 any Type and uniTypes

  • For unknown types, we can use any
  • Be cautious on any
let notSure: any = 4
notSure = "maybe it is a string"
notSure = true
  • Unitypes: could be a combined types
let numberOrString: number | string = 234
numberOrString = "a string"

// below will be an error
// numberOrString = true

2-4 Array and Tuple

  • Start with an array example
  • Is limited only to the type defined
let arrOfNum: number[] = [1,2,3,4]
arrOfNum.push(5)
  • arraylike objects in javascript
  • In javascript there are some data types similar to arrays but are not actually arrays
  • For example, arguments after defining a function
function test(){
// arguments is similar to an array
console.log(arguments)
console.log(arguments.length)
}
  • Tuples can contain different types
let user: [string, number] = ["this is a string", 20]

2-5 Interface

  • Describe the object shape
  • Class Abstraction
  • Duck Typing
interface Person {
name: string;
age: number;
}

let isaac: Person = {
name: "Isaac",
age: 20
}
  • Optional attribute
interface Person {
name: string;
// now age is optional
age?: number;
}

let isaac: Person = {
name: "Isaac",
}
  • ReadOnly
interface Person {
readonly id: number;
name: string;
age?: number;
}

let isaac: Person = {
id: 1234,
name: "Isaac",
}

// cannot change id, below will report error
// isaac.id = 3049

The difference between read-only and const

  • read-only is applied to the attribute
  • const is applied to the variable

2-6 Function

  • Fixed arguments
function add(x:number, y:number):number {
return x + y
}

let result = add(2,3)
  • Optional arguments
function add(x:number, y:number, z?:number):number {
if (typeof z === "number"){
return x + y + z
}
else {
return x + y
}
}

let result = add(2,3, 5)
let result2 = add(3,5)
  • Optional arguments cannot be placed after required arguments
// below will report error
function add(x:number, z?:number, y:number):number {
if (typeof z === "number"){
return x + y + z
}
else {
return x + y
}
}
  • Function Expression
const add = function add(x:number, y:number, z?:number):number {
if (typeof z === "number"){
return x + y + z
}
else {
return x + y
}
}

// below will report error
const add2: string = add

// correct
const add3:(x:number, y:number, z?:number) => number = add
  • In the example above, add3 was automatically determined the type based on TS type inference

2-7 Class One

  • Class defines the abstract attributes
  • Object: an instance of class
  • Four Principles of OOP:
    • Encapsulation: only expose interfaces
    • Inheritance: child class inherits parent class attributes, potentially with their own attributes
    • Abstraction: abstract attributes
    • Polymorphism: Different inherited classes might have different implementations for the same method
class Animal {
name: string;
constructor(name:string) {
this.name = name
}
run(){
return `${this.name} is running`
}
}

const python = new Animal("three")

console.log(python.run());

class Dog extends Animal {
bark(){
return `${this.name} is barking`
}
}

const lasse = new Dog("lasse")
console.log(lasse.run());
console.log(lasse.bark());

class Cat extends Animal {
constructor(name) {
super(name);
console.log(this.name);
}
run(){
return `Cat ` + super.run()
}
}

const cat = new Cat("Garfield")

console.log(cat.run());
```

## 2-8 Class Two

- There are three types of attributes
- public
- private
- protected

- public: we can change the attribute and

```typescript
class Animal {
public name: string;
constructor(name:string) {
this.name = name
}
run(){
return `${this.name} is running`
}
}

const python = new Animal("three")

console.log(python.run());
console.log(python.name)
python.name = "3.8"
console.log(python.name)
```

- private: for some attributes or methods inaccessible from the outsiders, including child class

```typescript
class Animal {
private name: string;
constructor(name:string) {
this.name = name
}
run(){
return `${this.name} is running`
}
}
  • protected: child class can access the protected attributes or methods
class Animal {
protected name: string;
constructor(name:string) {
this.name = name
}
run(){
return `${this.name} is running`
}
}
  • readonly: can only read but not edit
class Animal {
readonly name: string;
constructor(name:string) {
this.name = name
}
run(){
return `${this.name} is running`
}
}
  • static attributes and methods: can be accessed without instantiation
class Animal2 {
readonly name: string;
static categories: string[] = ["mammal", "bird", "others"]
static isAnimal(a) {
return a instanceof Animal2
}
constructor(name:string) {
this.name = name
}
run(){
return `${this.name} is running`
}
}

const snake = new Animal2("lily")

console.log(Animal2.categories)
console.log(Animal2.isAnimal(cat))
console.log(Animal2.isAnimal(snake))

2-9 Interface and Implements

  • Use interface and implements to abstract class attributes and methods

interface Radio {
switchRadio(trigger: boolean): void;
}

interface Battery {
checkBatteryStatus(): number;
}

interface RadioWithBattery extends Radio{
checkBatteryStatus(): number;
}

class Car implements Radio{
switchRadio(){

}
}

class Cellphone implements Radio, Battery{
switchRadio(){

}

checkBatteryStatus():number {
return 0
}
}

class Cellphone2 implements RadioWithBattery{
switchRadio(){

}

checkBatteryStatus():number {
return 0
}
}

2-10 Enumerates

enum Direction {
Up = 10,
Down,
Left,
Right
}

console.log(Direction.Left)
console.log(Direction[2])

2-11 Generics One

  • Generics: don’t specify the data type when defining a function or interface
function echo<T>(arg:T):T {
return arg
}

const res = echo("str")
  • Multiple values
function swap<T, U>(tuple:[T,U]):[U,T] {
return [tuple[1], tuple[0]]
}

const result = swap([1, "string"])
console.log(result)

2-12 Generics Two

  • Restricted Generics

interface IWithLength {
length: number,
}

function echoWithLength<T extends IWithLength>(arg: T): T {
console.log(arg.length)
return arg
}

const str = echoWithLength("string")
console.log(str);

const obj = echoWithLength({length: 10, name: "Isaac"})
console.log(obj);

2-13 Generics Three

  • Generics on Class
class Queue<T> {
private data = [];
enqueue(item: T){
return this.data.push(item)
}
dequeue(): T {
return this.data.shift()
}
}

const queue = new Queue<number>()
queue.enqueue(1)
queue.enqueue(2)
console.log(queue.dequeue().toFixed())
console.log(queue.dequeue().toFixed())

const queue2 = new Queue<string>()
queue2.enqueue("str")
queue2.enqueue("num")
console.log(queue2.dequeue().length)
console.log(queue2.dequeue().length);
  • Generics on Interface
interface KeyPair<T, U> {
key: T;
value: U;
}

let kp1: KeyPair<string,number> = {key:"A", value:2}
let kp2: KeyPair<number,string> = {key: 1, value:"str"}

let arr:number[]=[1,2,3]
let arr2:Array<number> = [1,2,3]
  • Interface with function
interface IPlus {
(a: number, b:number) : number
}
function plus(a:number, b:number) :number {
return a + b
}

const res:IPlus = plus
  • Generic Interface with Function
interface IPlus<T> {
(a: T, b:T) : T
}
function plus(a:number, b:number) :number {
return a + b
}
function connect(a:string, b:string):string {
return a + b
}
const res:IPlus<number> = plus
const res2:IPlus<string> = connect

console.log(res(9,8))
console.log(res2("hello", "world"))

2-14 Type aliases

  • to define a function
function sum(x:number, y:number):number {
return x + y
}

const sum2: (x:number, y:number) => number = sum
  • alternatively, can use type aliases
function sum(x:number, y:number):number {
return x + y
}

type PlusType = (x:number, y:number) => number

const sum2:PlusType = sum
  • join type
type NameResolver = () => string
type NameOrResolver = string | NameOrResolver
function getName(n:NameOrResolver):string {
if (typeof n === "string") {
return n
} else {
return n()
}
}
  • type assertion
function getLength(input:number|string) :number {
const str = input as String
if(str.length){
return str.length
} else {
const num = input as number
return num.toString().length
}
}

an easier way to write above

function getLength(input:string|number):number {
if((<string>input).length){
return (<string>input).length
} else {
return input.toString().length
}
}

2-15 Declare File

  • Declare var to use 3rd party libraries
declare var jQuery: (selector: string) => any
  • Save the above in a .d.ts file, e.g. jQuery.d.ts

  • tsconfig file

{
"include": ["**/*"]
}

   Reprint policy


《Get Started with Typescript》 by Isaac Zhou is licensed under a Creative Commons Attribution 4.0 International License
  TOC