Definitelytyped: React Component static properties

Created on 5 Jun 2017  路  2Comments  路  Source: DefinitelyTyped/DefinitelyTyped

React鈥檚 Component class supports static properties such as displayName, defaultProps, propTypes, and others.

When creating a component class, the common practice seems to be to extend the Component class type. However, the Component class type does not include these static properties. This means you don't get errors for these static properties:

import React, { Component, ComponentClass } from 'react';

type Props = { name: string };

{
  class ReactComponent extends Component<Props, any> {
    // expected error, but got none: displayName should be a string
    static displayName = 1
    // expected error, but got none: defaultProps.name should be a string
    static defaultProps = { name: 1 }
  };
}

These static properties have instead been defined on a separate type, the ComponentClass interface. In order to get type checking for these static properties, one has to annotate the class using this interface:

{
  // error: displayName should be a string
  // error: defaultProps.name should be a string
  const ReactComponent: ComponentClass<Props> = class extends Component<Props, any> {
    static displayName = 1
    static defaultProps = { name: 1 }
  };
}

Is there any way we can consolidate these two types, so we get free type checking of static properties simply by extending Component?

/cc React type definition authors: @johnnyreilly @bbenezech @pzavolinsky @digiguru @ericanderson

Most helpful comment

To address this I think we need TypeScript to have the ability to have abstract static properties/methods in abstract classes: https://github.com/Microsoft/TypeScript/issues/14600#issuecomment-308362119

All 2 comments

To address this I think we need TypeScript to have the ability to have abstract static properties/methods in abstract classes: https://github.com/Microsoft/TypeScript/issues/14600#issuecomment-308362119

AFAICT, it should work to just copy the contextTypes, childContextTypes, and displayName declarations to the Component class as optional static properties. I don't see how Microsoft/TypeScript#14600 is relevant, given that the properties are optional. If they were required, then we would need Microsoft/TypeScript#14600.

defaultProps and propTypes cannot be copied because they would be static properties that depend on P, which is an instance type parameter. Any TypeScript suggestion to provide a way out of that problem seems likely to me to be a stretch. See #28515 for what I believe is the best current solution for defaultProps and propTypes. Note that converting to React.ComponentClass gives you _checking_ of the defaultProps and propTypes but (according to my tests) not _contextual typing_, which would be highly desirable.

Was this page helpful?
0 / 5 - 0 ratings