Skip to content

Latest commit

 

History

History
594 lines (441 loc) · 17.1 KB

README.md

File metadata and controls

594 lines (441 loc) · 17.1 KB

Getting started with TypeScript

TypeScript is an open source language and is a superset of JavaScript created by Microsoft.

More about TypeScript

  • Offers additional features to JavaScript including static types
  • Using types is completely optional
  • Compiles down to regular JS
  • Can be used for front-end JS as well as backend with Node.js
  • Includes most features from ES6, ES7 (classes, arrow functions, etc)
  • Types from 3rd party libraries can be added with type definitions.
  • Based on the .NET harmony specification

What's wrong with JavaScript

  • Not suitable for large applications
  • Lacks strong typing
  • Weird inheritance, unfamiliar syntax
  • Only errors during runtime
  • Suffers type coercion

Dynamic vs Static Typing

Dynamic Static
In dynamically typed languages, the types are associated with run-time values and not named explicitly in your code In statically typed languages, you explicitly assign types to variables, function parameters, return values, etc
Eg. JavaScript, Python, Ruby, PHP Eg. Java, C, C++, Rust, Go

Pros & Cons of TypeScript

Pros Cons
More Robust More Code to Write
Easily spot Bugs More To Learn
Predictability Required Compilation
Readability Not True Static Typing
Popular

States of Compiling TypeScript


  • TypeScript uses .ts and .tsx (working JSX like React) extension
  • TSC (TypeScript Compiler) is used to compile .ts file down to JS
  • Can watch files and report errors at compile time
  • Many tools include TS compilation by default
  • Most IDEs have great support for TS
  • The tsconfig.json file is used to configure how TypeScript works

Lets make our hand dirty with TypeScript


Environment Setup:

  • First we need to install TypeScript globally in our machine
    • Using npm npm i -g typescript
    • Using yarn yarn global add typescript
  • Create a folder with .ts extension
  • Check TypeScript version by running this tsc -v on your terminal
  • In the terminal type tsc fileName.ts it will compile ts file down to js
  • To manage how to compile a typescript file in terminal type tsc --init
  • And it will create a tsconfig.json file where you can manage your ts file compilation and others
  • tsconfig.json is the configuration file for TypeScript project
  • You are all done to maker your hands dirty with ts

Basic Types in TypeScript


I assume you know what is variable in JS (to remind you again, variables are like container where we can store data/values and can access or modify them later)

Steps to create a variable with types in Typescript

  • variable-keyword(var/let/const)
  • variableName(studentName, id etc)
  • colon(:)
  • what type of variable it is? (number, string etc)
  • assignment-operator(=)
  • value of that type
// example: 
let studentName: string = "Jisan"
const studentId: number = 3

Some other types are:

  • number
  • string
  • boolean
  • any

Note-1: If we explicitly set types to variables the value cannot be changed to another types of value. In other word A variable declared with a particular type of value cannot be changed to another type of value

let salary: number = 20000
salary = 'twentyK' // error

Note-2: But when we explicitly set a variable type to any, we can change this with any other types of value later.

let x: any = 'hi'
x = 5 // ok

Note-3: When we just declare a variable with no types and values. TypeScript give any types to this variable automatically.

let a; // it has any type
a = true

Note-4: When we declare a variable and assign a value, but don't set any type to this. In that case TypeScript will set its type according to the value. In TS it's called type inference in TypeScript.

let z = 10 // it has number type
z = 'hi' // error

Other Example of Variables

let studentId: number = 5;
let studentName: string = 'Jisan';
let isPresentToday: boolean = true;
let x: any = 'Hi';
x = 10

Arrays


Lets say we need an array of number/string etc.

  • We can define types of array values by writing the type of values and bracket [] eg. let nums: [number]
  • Now, we cannot add values to that array of another types
  • Note: if the type is any(any[]) then we can add different types values on that array eg. let arr: any[] = [1, 'hi', true]
// examples
let nums: number[] = [1, 2, 3, 4, 5]3
let arr: any[] = [5, false, 'hello']

Tuples


If we don't want to set any[] type to array instead we want to set types for every value of an array.

  • Here we can use tuple below is an example
   
let person: [number, string, boolean] = [3, 'Jisan', true]

// Tuple array
let employee: [number, string][]

employee = [
  [5, 'Jack'],
  [6, 'Doe'],
  [7, 'Jhon']
]

Union


  • Lets say, wee have some products and each has productId, the value of this can be a number or a randomly generated string

  • Question is how do we set type to variable which value could be one or another types?

  • Here it come union, all we need to do is set multiple types separated a Pipe ( | ) character

// example
let productId: number | string;
productId = '234xcfswe323'
productId = 3321

Enum or enumerate types


Enum allows us to define a set of named constants. Using enums can make it easier to document intent, or create a set of distinct cases. TypeScript provides both numeric and string-based enums.

To define/create an enum

  • write enum keyword(enum)
  • enum name with Capital (first letter)
  • second bracket {}
  • constants separated by comma (,)
    • By default constants value are numeric and starts from 0
    • if we explicitly set values (numeric) to any particular enum constant, other constants (which are after that constant) value would be incremented by one
    • on the other hand, if we explicitly set value to one of the constants as string, we need to set value to the next constant as well.

To get enum particular constant value

  • First type enum Name(SubjectsCodes)
  • dot(.) and
  • constant name inside that enum(math)
// examples
enum Directions {
  top, // value is 0
  right, // value is 1
  bottom = 5,  // value is 5
  left // value is 6
}

enum SubjectsCodes {
  math = '23432',
  physics = '34234',
  chemistry = '32423'
}

console.log(SubjectsCodes.chemistry)

Objects


We have a student object which includes id and name attributes. Now, how to set types for id and name for this object.

Follow the blow example

// one way of writing types for objects
const student: {
  id: number,
  name: string
} = {
  id: 2,
  name: 'Jisan'
}


// another way is to create type in external variable for the object like this
type Student1 = {
  id: number,
  name: string
}

const student1: Student1 = {
  id: 1,
  name: 'Jisan Mia'
}

Type Assertion


  • Let's assume we have a variable named code with a type of any and value 213
  • we have another variable named employeeCode. It uses the code variable value as its value.
  • but in this case we know that the number of employeeCode must be a number. though we already assigned code which has any type
  • in this case we can use type assertion to say that employeeCode value is number

there are two ways to do type assertion in ts below are examples

// 1. using angular bracket
let code: any = 200;
let employeeCode = <number> code;

// 2. using as keyword
let employeeCode2 = code as number;

Functions


  • in functions we can give type to arguments as well as to the return value
  • arguments types define what types of value we can pass
  • return type defines what types of value we can return from a function

Note-1: In case we want an argument optional, mean we can both pass and not pass that argument in function call. For this we can make arg. optional by adding question mark (?) at end of arg. name

Note-2: Sometimes we don't want to return any any value from function, maybe we just want to console.log() something. In that case we can use void as function return type

// examples
function addTwoNum(a: number, b: number): number {
  return a + b;
}
console.log(addTwoNum(5, 20))

// function that return void(nothing)
function logMe(message: string): void {
  console.log(message)
}
logMe('Hey, me void')

Type Aliases


with type alias we can make type schema or structure objects, function arguments, variables etc To create type aliases

  • type keyword
  • type alias Name
  • and then types schema
// examples
type StudentDetails = {
  name: string;
  age: number; 
  isCaptain?: boolean;
  semester: number;
}

type stringOrNum = string | number

function getStudentDetails(studentDetails: StudentDetails, classTeacherId: stringOrNum): string {
  return `
      name: ${studentDetails.name}
      age: ${studentDetails.age}
      isCaptain: ${studentDetails.isCaptain}
      semester: ${studentDetails.semester}
      classTeacherId: ${classTeacherId}
    `
}

const studentDetail1 = getStudentDetails({name: 'Jisan', age:19, isCaptain: true, semester: 3}, 324422)

const studentDetail2 = getStudentDetails({name: 'Rahman', age:20, semester: 3}, '4523x4')
console.log(studentDetail2)

Interfaces


Interface is kind of like specific structure of types for an object or functions

To create interface

  • interface keyword (interface)
  • interface name(EmployeeInterface)
  • bracket {}
  • propertyName : valueTypes

To use interface for object as its types

  • var/let/const

  • objName (employeeObj)

  • colon (:)

  • interfaceName (EmployeeInterface)

  • assignment (=) and bracket {}

  • inside bracket key-value pair as defined in the interface

  • Sometimes, we don't want each and every property of an interface to be mandatory. if we want we can make an interface property optional by adding a question mark(?) to the end of their names.

  • also we can make particular property to be read only by using readOnly keyword before their names

// interface with objects
interface EmployeeInterface {
  readonly id: number,
  name: string,
  age?: number
}

let employeeObj: EmployeeInterface = {
  id: 23,
  name: 'Jhon',
}
employeeObj.name = 'Mark' 

employeeObj.name = 'Mark' // can change
// employeeObj.id = 5 // can't change as id is readOnly

Note: We cannot use union and primitive in interface

We can do this

type Pointer = number | string
const p1: Pointer = 1

But cannot in interface

interface Pointer = number | string; // error
const p1: Pointer = 1

Interface with functions


interface MathFunc {
  (x: number, y: number) : number
}

const add: MathFunc = (x: number, y: number) : number => x + y

Classes


Classes are now available in JavaScript since es6 were introduced. Classes are used to create objects(multiple) or class is a blueprint of object

To create class->

  • first class keyword (class)
  • class Name (Person)
  • bracket {} and some properties(class can have properties and methods)
  • constructor method
    • it is a method where we need to initialize values for class properties
    • constructor method/function will run whenever we instantiated an object
    • so we can pass parameters to constructor and initialize those to properties by adding this keyword and dot (this.) before property name

There is another thing called Access Modifiers

  • now Person class properties are public(by default) means we can access/modify there values outside of that class
  • we can make properties private by adding private keyword before properties name (mean we can only access/modify these properties withing the class)
  • we can make properties protected by adding protected keyword before properties name (access it only access within either this class or any class that is extended from this class )
  • also we can make particular property to be read only by using readOnly keyword before their names like objects. readOnly properties are only accessible not change/modifiable.
// examples
class Person {
  private id: number
  protected roomId: string
  firstName: string
  lastName: string


  constructor (id: number, roomId: string, firstName: string, lastName: string) {
    this.id = id
    this.roomId = roomId
    this.firstName = firstName
    this.lastName = lastName
  }

  // methods
  getFullName() {
    return `Full Name: ${this.firstName} ${this.lastName}`
  }
}

// initializing/instantiated an object to Person class

const jisan = new Person(25, '23432', 'Jisan', 'Mia')

const mark = new Person(33, '323s4', 'Mark','Adher')

// calling getFullName method of Person class with jsian object
console.log(jisan.getFullName())

Implement interface in class


Create an interface for student information then implement it on class following below

interface studentInterface {
    roll: number
    name: string
    isPresent: boolean
    checkAvailability(): string
}

class StudentInfo implements studentInterface {
  roll: number
  name: string
  isPresent: boolean

  constructor (roll: number, name: string, isPresent: boolean) {
    this.roll = roll
    this.name =  name
    this.isPresent = isPresent
  }

  checkAvailability() {
    return `${this.name} is ${this.isPresent ? 'present' : 'not present'}`
  }
}

const studentOne = new StudentInfo(1, 'Jisan', true)
const studentTwo = new StudentInfo(2, 'Mursalin', false)

console.log(studentOne.checkAvailability())

Guess What? There is another cool thing to explore. Suppose, now we need an array of allStudents created by that class

  • what would be the type allStudents array
  • there is thing, we can use the StudentInfo class as allStudents array type
  • now we don't need to worry much about allStudents array types
const allStudents: StudentInfo = [];
allStudents.push(studentOne)
allStudents.push(studentTwo)

Extending classes or subclasses


Let's imagine we need teachers objects, for this we can create Teacher class. Now think of the possible properties for a teacher.

  • teacher has id/roll
  • teacher has name
  • teacher can be present or absent
  • teacher has a position(head, assistant etc)

Comparing teacher with student, teacher has 4 property and 3 of them are same as student properties,

  • and the 4th property of teacher is new
  • So what we do, shall we create teacher class with all properties again,
  • or is there any way to use Student class in Teacher class
  • Yeah, there is.
  • we can extend StudentInfo class to Teacher class by using extends keyword.
  • and in constructor use super keyword to call the members(properties, methods) of the Super class(StudentInfo).
  • Teacher as a subclass of StudentInfo inherits all the members(fields, methods etc).
  • and since constructs are not members they are not inherited by subclasses.
// subclass
class Teacher extends StudentInfo {
  position: string

  constructor(roll: number, name: string, isPresent: boolean, position: string) {

    super(roll, name, isPresent)
    this.position = position
  }
}

const teacher1 = new Teacher(2313, 'Rahman', true, 'Head')
const teacher2 = new Teacher(3423, 'Arif', false, 'Assistant')

console.log(teacher1.position)

// calling student class method from teacher a object created from teacher class
console.log(teacher2.checkAvailability())

Generics


Now, we want a reusable function that can perform some task for different types of values

  • lets say we have a function that takes array as arg. and return arr
  • the array values type can be number or string
  • we can use any type to function
  • but if we do that, we won't get any error when we push different types values to the array
  • to solve this problem we can use generics

To implement this ->

  • after function name, use angular bracket(<>)
  • inside <> write something and then use this word as type for parameter and return value
  • when we call this function with array of number or string as parameter
  • we should write the respected type of array value after the function name
  • ex functionName<typeName>([value])
  • that's it
// examples
function getArray<Type>(item: Type[]): Type[] {
  return new Array().concat(item)
}

const numArr = getArray<number>([1, 2, 3, 4])
const strArr = getArray<string>(['jisan', 'shawon', 'Porag'])

// numArr.push('something') we cannot add string to number array

// strArr.push(5) we cannot add numbers to string array

Resources: that I used to write this wonderful document about TypeScript