Search code examples
typescriptdecoratortypescript-generics

if <T> is a type of Class/Constructor then why do we need to extend it to an object over here?


If <T> is a type of Class/Constructor then why do we need to extend it to an object over here? and how the object we are extending is receiving the Arguments? Can somebody please explain me what happened in the Decorator Function

interface MapLocation {
  lat: number;
  long: number;
}
        
function AddLocation(lat: number, long: number) {
  return <T extends { new (...args: any[]): {} }>(
    classConstructor: T
  ) => {
    return class extends classConstructor {
      public mapLocation: MapLocation;
      constructor(...args: any[]) {
        super(...args);
        this.mapLocation = { lat, long };
        }
     };
  };
}
    
@AddLocation(1.234, 1.876)
class Person {
  constructor(public name: string, public age: number) {}
}

Solution

  • T extends { new (...args: any[]): {} }
    

    means that T should be a constructor
    It may be written more simple as

    T extends new(...a:any[])=>any
    

    Decorator as basically a function, and this allows to disallow to run in over a non-conltructor

    AddLocation(1, 2)( {} ) // error
    class X{
       @AddLocation(1, 2) // error
       f(){}
       @AddLocation(1, 2) // error
       val = 123;
    }
    

    The constructor passes its arguments as argument list

    function getArgs(...a: any[]) { return a }
    let a = getArgs(1, 2, 3) // [1, 2, 3]
    console.log(...a) // 1 2 3