1

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)

Playground

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. 

Playground

I understand that something about React.Component makes it incompatible, but what is it and is there a way to work around it?

1
  • 1
    This is because the new signatures do not match, as you can see here. Commented Sep 29, 2022 at 14:57

1 Answer 1

1

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
}

Playground Link

You could also make it accept just one param (the props) like this: new(props: any): CLike

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.