Reputation: 1719
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
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