Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you type a class decorator in typescript?

Tags:

typescript

What would be the correct way to write a class decorator which accepts only specific classes?

I tried the following:

class Component {
  age: number;
}

function registerComponent(name: string) {
  return <T extends Component>(constructor: T): T => {
    return constructor as T;
  }
}

@registerComponent("demo")
class C1 extends Component {

}

Which results in:

Argument of type 'typeof C1' is not assignable to parameter of type 'Component'.
  Property 'age' is missing in type 'typeof C1'.

Try in TypeScript Repl

like image 896
jantimon Avatar asked Jul 18 '17 07:07

jantimon


People also ask

What is a class decorator TypeScript?

The TypeScript website describes it as: “A Decorator is a special kind of declaration that can be attached to a class declaration, method, accessor, property, or parameter.” I would describe it as “a special declaration to add extra features on an existing class declaration, method, accessor, property, or parameter.”

Can we use decorator on class?

In Python, decorators can be either functions or classes. In both cases, decorating adds functionality to existing functions. When we decorate a function with a class, that function becomes an instance of the class. We can add functionality to the function by defining methods in the decorating class.

How are decorators used in class?

To decorate a method in a class, first use the '@' symbol followed by the name of the decorator function. A decorator is simply a function that takes a function as an argument and returns yet another function. Here, when we decorate, multiply_together with integer_check, the integer function gets called.

How do you write a decorator in JavaScript?

Decorators use a special syntax in JavaScript, whereby they are prefixed with an @ symbol and placed immediately before the code being decorated. Note: at the time of writing, the decorators are currently in “Stage 2 Draft” form, meaning that they are mostly finished but still subject to changes.


1 Answers

What gets passed to the decorator is the type, not an instance of the type. Saying constructor: T means constructor must be an instance of type T, so instead you have to tell it that the parameter and the result are both constructors for the type T:

class Component {
  age: number;
}

function registerComponent(name: string) {
  return <T extends Component>(constructor: new () => T): new () => T => {
    return constructor;
  }
}

@registerComponent("demo")
class C1 extends Component {

}

and you would get an extra +1 for including the typescript repl if I could. Made it very easy to check my answer.

Note that you might also want to specify the constructor parameters.

like image 118
Duncan Avatar answered Oct 14 '22 11:10

Duncan