Understanding Typescript In Depth

Learn Typescript in Depth
    // welcome beack guys lets Learn Typescript 
    
    
    console.log("Hello from JavaScript");
    console.log("Hello from JavaScript");
    console.log("Hello from JavaScript");
    function switchFunction(num: number):string {
      let b: string = "functionb";
    
      switch (num) {
        case 1: {
          let b: string = "case 1";
          break;
        } // After break
        case 2:
          {
            let b: string = "case 2";
          } // Before break
          break;
      }
    let n1 : string | undefined = Math.random() > 0.5 ? undefined : 'test'
    
    function f1(optional? : string) : undefined | string {
        if(optional === undefined){
            return undefined
        }
        else {
            return optional; 
        }
    }
    f1('hello');
    
    
    // non premitive group in typescript 
    // string , void, tuple, any, never, unknown 
    function returnNever(i: number): never{
        if(i === 0){
            throw Error('invalid value');
        }
        else {
            throw Error('i is not 0');
        }
    }
    
    type myUnion = 'a' | 'b' ;
    
    function checkValue(value : myUnion){
    let list : number [] = [2,3,4,5,6];
    
    let list1 : Array<number> = [3,4,5,6,7];
    let list2 : Array<number> = new Array<number>(1,2,34,4);
    
    let list3 : (number | string)[] = [1,2,3,4,'hello'];
    let list4 : Array<number | string> = [1,2,3, 'hello'];
    let list5 : Array<number | string> = new Array<number | string>(1,2,3, 'hello');
    
    
    // http://www.typescriptlang.org/play/
    
    enum Weather {
      Sunny,
      Cloudy,
      Rainy,
      Snowy
    }
    let today: Weather = Weather.Cloudy;
    let tomorrow: Weather = 200;
    console.log("Today value", today); // Today value 1
    console.log("Today key", Weather[today]); // Today key Cloudy
    enum Weather1 {
      Sunny = 100,
    interface Book {
        type : "Book",
        isbn: string,
        page: number
    }
    interface Movie {
        type: "Movie",
        lengthInMin: number
    }
    
    let hobby: Movie = {type : "Movie", lengthInMin : 120}
    
    function showHobby(hobby : Book | Movie){
        if(hobby.type === 'Book'){
    console.log("Hello from JavaScript");
    let map = new Map();
    let set = new Set();
    
    let map1 = new Map<string, number>();
    map1.set('hello', 6);
    
    let map2 = new Map<string, number>([["hello", 1], [8, 8]]);
    let x : Object = 'c';   // Object 
    let x1 : Object = true;
    let x2 : Object = {};
    let x3 : Object = Object.create({});
    
    let y : object = {};
    let y1 : object = new Date();
    let y2 : object = Object.create({})
    let y3 : object = [1,3,4,5];
    // let y4 : object = new hello();
    null
    undefined 
    var v1 : null | undefined | string = 'hello';
    
    // Object & object
    let obj1: Object = {};
    let obj2: object = {};
    let obj3: {} = {};
    let obj4: any = {};
    
    obj2.test = "3";
    obj3.test = "3";
    obj4.test = "3";
    
    
    obj1.toString();
    obj2.toString();
    obj23.toString();
    class classToConstruct {
        constructor(){}
    }
    const obj = new classToConstruct();
    
    function sayHello(){}
    const fnObj = new sayHello();
    
    interface MyObject {
        a: number,
        b :string,
        c? :string,
        d: number
    };
    interface TypeA {
        a :string
        b:string
    }
    interface TypeB {
        a :string
        b:string
    }
    
    type TypeC = TypeA & TypeB;
    const m : TypeC = {
        a: "A"
        b: "b"
        C: "c"
    interface TypeA {
        a: string
        b:string
    }
    function intersectGenerics<T1>(t1: T1): T1 & TypeA {
        const x : TypeA = {a: "A" , b : "B"};
        return (<any>)
    }
    interface TypeA {
        m1 : string
    }
    interface TypeB {
        m2 : string
    }
    type D5 = TypeA | TypeB;
    
    interface TypeC extends TypeA {
        m4 : string
    }
    class X implements TypeA {
        public m1:string
    }
    interface InterfaceA {
      m1: string;
    }
    interface InterfaceB {
      m2: string;
    }
    type TypeAB = InterfaceA & InterfaceB;
    
    interface X1 {
      m1: string;
    }
    interface X2 {
      m1?: string;
    }
    interface X {
        sayHi(x:null) :void
        sayHello(param:string): string
        sayGreetings<T>(T):T
    }
    class hello implements X {
        public sayHi(x :null){
        }
        public sayHello(x :string){
            return '';
        }
        say
    }
    
    // tuple type 
    let tuple1 = ["hello", "worls", 6898]; // (string | number) []
    
    tuple1[2] = "not a nulmber";
    
    let tuple2 : [string, string, number] = ["hello", "world", 6788];
    tuple2[2] = "hello";
    
    function result(...args : [number, string, boolean]): void{
        // todo
    }
    let tuple4 : [number, string, boolean] = [3,'hello', true];
    // let tuple5 : (number, string, boolean)[] = [3,'hello', true];
    
    console.log("Hello from JavaScript");
    export class variable {
        public a:string = 'hello';
        private b :number = 90;
        protected c : null | string = null;
        d : number = 90;
        public e : any = 80;
    }
    const obj = new variable();
    
    class Myclass {
        private p1 : number;
        private p2 : Boolean;
        private p3 : string;
        constructor(para1 : number, para2: Boolean, para13 : string){
    class classWithOveraload {
        private x1:number;
        private x2?:string;
        constructor(x1:number);
        constructor(x1:number, x2 : string){
            this.x1 = x1;
            if(x2 === undefined){
                x2 = 'default';
            }
            this.x2 = x2; 
        } 
    }
    class BaseClass {
        public a: number = 1;
        private b: number =2;
        protected c: number =3;
        public functi():void {
            this.a;
            this.b;
            this.c
        }
    }
    
    class chilClass extends BaseClass {
        public d: number = 3;
        private e: number = 7;
    class Greeter<T> {
        greeting: T;
        constructor(message: T) {
            this.greeting = message;
        }
        greet() {
            return this.greeting;
        }
    }
    let greeter = new Greeter<string>("Hello, world");
    let greeter1 = new Greeter<number>(2);
    
    
    let button = document.createElement('button');
    abstract class FakeClass {
        public static m1: string;
        public static F1():void {}
    }
    FakeClass.m1 = 'hello';
    
    class staticClass {
        public static pa:number;
        private static privateStaticNum : number;
    }
    class privareCons {
        private constructor(){
            
        }
    class ClassA {
        constructor(){
            
        }
      public mainFunction(): void {
        this.subFunction1();
        this.subFunction2();
      }
      private subFunction1(): void {}
      private subFunction2(): void {}
    }
    interface IClassA {
      mainFunction(): void;
    }
    const a = "test";
    let b: number = 2;
    const c: boolean = true;
    let d: number | string | null | boolean = "test";
    console.log(typeof a); // string
    console.log(typeof b); // number
    console.log(typeof c); // boolean
    console.log(typeof d); // string
    
    let g1: number | undefined = undefined;
    let h1: number | undefined | null = null;
    console.log(typeof g1); // undefined
    console.log(typeof h1); // object 
    
    interface MyCustomTypeA {
          test:string
    }
    interface MyCustomTypeB {
        anything:string
    }
    interface reusableInterface<T> {
        entity : T
    }
    
    const r1 : reusableInterface<MyCustomTypeA> = { entity : {test : "yes"}};
    const r2 : reusableInterface<MyCustomTypeB> = { entity : {anything : "yes"}};
    
    const r3 : reusableInterface<number> = { entity : 1} ;
    // read it
    function genericsTypes<T>(list: T[], param2: number): T {
      console.log(param2);
      return list[param2];
    }
    // extending genrics types
    interface AnyKindOfObject {
      what: string;
    }
    
    interface reuseableTypes<T extends object> {
      entity: T;
    }
    
    function merge<T, U>(Obj1: T, Obj2: U): T & U {
        return Object.assign({}, Obj1, Obj2);
    }
    
    function shows<T>(p1? : T): void {
        console.log(p1);
    }
    shows();
    shows("12345");
    shows({});
    
    // generics with union 
    
    interface objectWithAge{