Definitelytyped: refs field on custom react component not allowed

Created on 13 Aug 2015  路  4Comments  路  Source: DefinitelyTyped/DefinitelyTyped

The following code:

/// <reference path="../typings/tsd.d.ts" />
import * as React from "react"

class ComponentA extends React.Component<{}, void> {
  render() { return <div>ComponentA</div> } }

class ComponentB extends React.Component<{}, void> {
  render() { return <ComponentA ref="a" /> } }

gives the following error:

at line 8, file [omitted] Property 'ref' does not exist on type '{}'.

This is in fact valid react code, and it works on elements like <div>, but not custom ones. I spent some time trying to dig into the code, but it's not obvious to me how the whole JSX.Element type works, it seems to be some magic in the TypeScript compiler. I thought I'd post it up here before I spent too much time in case it's obvious to someone else.

Most helpful comment

interface ComponentAProps extends React.Props<ComponentA> {
}
class ComponentA extends React.Component<ComponentAProps, {}> {
}

All 4 comments

@jbrownson please send a pull requet. I'll review it.

The issue is that the props for ComponentA are determined by the props that you specified when creating ComponentA. When you say class ComponentA extends React.Component<{}, void> you are saying that the props for ComponentA are {}. When you later try to use ref as a prop it does not work.

Try something like class ComponentA extends React.Component<{ref: string}, void>.

I can see if there's a way we can have a set of intrinsic properties like ref.

interface ComponentAProps extends React.Props<ComponentA> {
}
class ComponentA extends React.Component<ComponentAProps, {}> {
}

I see that the interface docs for React.Props<T> state that this interface is deprecated. Is there currently a non-deprecated way to achieve this? If not, then the deprecation warning should be removed.

Was this page helpful?
0 / 5 - 0 ratings