I got this to work with regular classes, including classes that extend the target class as you can see below:
interface ALike {
a: () => boolean
}
interface ALikeConstructor {
new (): ALike
aStatic: () => boolean
}
function acceptsALike(ctr: ALikeConstructor) { }
class A {
public a() {
return true;
}
public static aStatic(): boolean {
return true;
}
}
class AB extends A {
public b() {
return true;
}
}
class ANoStatic {
public a() {
return true;
}
}
acceptsALike(A); // ok
acceptsALike(AB); // ok
acceptsALike(ANoStatic); // ok (error shows)
However, for whatever reason it does not work with React components and TypeScript does not give much of an explanation.
import React from 'react'
type Props = {
test: true
}
interface CLike extends React.Component<Props> {
c(): boolean
}
interface CLikeConstructor {
new(): CLike
cStatic(): boolean
}
class C extends React.Component<Props> implements CLike {
public c() {
return true;
}
public static cStatic() {
return true;
}
}
function acceptsCLike(ctr: CLikeConstructor) { }
acceptsCLike(C); // Argument of type 'typeof C' is not assingable to parameter of type 'CLikeConstructor' - no further explanation.
I understand that something about React.Component makes it incompatible, but what is it and is there a way to work around it?
CodePudding user response:
The problem is that your constructor signature (in CLikeConstructor
) describes a constructor with no arguments. The react class has a constructor with one argument (the props).
You can defined the constructor signature to not care about the number of args:
interface CLikeConstructor {
new(...a: any[]): CLike
cStatic(): boolean
}
You could also make it accept just one param (the props) like this: new(props: any): CLike