Home > Blockchain >  TypeScript - declare type of a React component class constructor with a certain static method
TypeScript - declare type of a React component class constructor with a certain static method

Time:09-30

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?

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
}

Playground Link

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

  • Related