Ziyu Zhou
Ziyu Zhou

Reputation: 1719

TypeScript generic Error when writing a decorator?

When using React 16 new feature: componentDidCatch, I try write a HOC to abstract the code. And implement it with decorator. Code below:

import * as React from 'react';
export function catcher<P, T extends React.ComponentClass<P>>(Target: T): T {
  class HOC extends Target {

  }
  return HOC;
}

and just using it like:

@catcher
export class Foo extends React.Component {}

BUT, errors occurs

[ts] Type 'T' is not a constructor function type.

[ts] Type 'typeof HOC' is not assignable to type 'T'

Upvotes: 0

Views: 443

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249476

The docs say that the first argument to the decorator is a the constructor, so we have to give T a constructor signature. The example in the docs has the constructor returning {}, but if we want to make sure the decorator cannot be used on just any type and must be used on a React.Component we can have the constructor return a React.Component, so any constructor passed will have to return a React.Component or compatible (in effect will have to be derived from React.Component)

export function catcher<S, P, T extends { new (... args:any[]): React.Component<S, P>  }>(constructor:T) {
  class HOC extends constructor {

  }
  return HOC;
}

@catcher
export class Foo extends React.Component {
}

@catcher // Will be an error, Foo2 is not derived from React.Component
export class Foo2  {
}

An alternative syntax for the signature of the constructor is:

export function catcher<S, P, T extends new (... args:any[]) => React.Component<S, P>>(constructor:T) {
  class HOC extends constructor {

  }
  return HOC;
}

Upvotes: 1

Related Questions