marcius.tan
marcius.tan

Reputation: 97

Typescript Documentation on Class Decorator - function returning "class extends constructor {}"

So, I am trying to build understanding about Typescript Decorators and I have been stuck on the example given about Class decorators. The example given shows how to form class decorator through function(){}.

  function classDecorator<T extends {new(...args:any[]):{}}>(constructor:T){
        return class extends constructor {
            newProperty = "new property";
            hello = "override";
        }
    }    

    @classDecorator
    class Greeter {
        property = "property";
        hello: string;
        constructor(m: string) {
            this.hello = m;
        }
    }    

    console.log(new Greeter("world"));

What is the:

return class extends constructor {
    newProperty = "new property";
    hello = "override";
}

How can a function returning a "class" keyword that extends a parameter (called "construct")? I am so confused.

Here is link to original source (just scroll to the middle section on class decorator): https://www.typescriptlang.org/docs/handbook/decorators.html

Appreciate any help!

Upvotes: 4

Views: 1850

Answers (2)

Jackie Li
Jackie Li

Reputation: 11

As to "class extends", It is ES6 javascript syntax : "class expression"

you can test this code in fiddle:

class Car {
    constructor(brand) {
    this.carname = brand;
  }
  present() {
    return 'I have a ' + this.carname;
  }
}

const Model = class extends Car {
  constructor(brand, mod) {
    super(brand);
    this.model = mod;
  }
  show() {
    return this.present() + ', it is a ' + this.model;
  }
}

console.log(new Model("Ford", "Mustang").show());

---result: "Running fiddle" "I have a Ford, it is a Mustang"

Upvotes: 0

Andrew Eisenberg
Andrew Eisenberg

Reputation: 28757

You need to look at the full declaration of the decorator:

function classDecorator<T extends {new(...args:any[]):{}}>(constructor:T) {
    return class extends constructor {
        newProperty = "new property";
        hello = "override";
    }
}

It's pretty gnarly, but here's what's going on.

The type of constructor is something that satisfies the T type parameter.

This type parameter T extends {new(...args:any[]):{}} applies to any object that has a constructor that takes any number of arguments of any type (i.e., pretty much anything).

What this decorator does is instead of returning the constructor that is passed in, a different class is returned.

Note that the syntax return class { ... } is a way to return an anonymous class from a function, much like return function() { ... } returns an anonumous function.

And class extends constructor means that the anonymous class inherits all of constructor's methods and properties (constructor is the class being decorated).

Upvotes: 3

Related Questions