Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to type a React component definition?

I am trying to statically type the props of a React component. After including the definitions for React, I have defined a typed variation of React.createClass named component.

interface Component<P> {
    (props: P, ...children: any[]): React.ReactComponent<P, any>
}

function component<P, S>(spec: React.ReactComponentSpec<P, S>): Component<P> {
    return React.createClass(spec);
}

When I define a Label Component with an annotation that says that it takes a text string prop,

var Label: Component<{text: string}> = component({
    render: function() {
        return React.DOM.div(null, this.props.text);
    }
});

var App = React.createClass({
    render: function() {
        return React.DOM.div(null, Label({text: "Hello"}));
    }
});

the compiler checks that Label is called with a text property and that it is a string.

The next step is to have the compiler check this.props.text uses inside the Label methods. How to do it?

like image 571
Valéry Avatar asked Aug 10 '14 22:08

Valéry


People also ask

How do you define a component in React?

React is also capable of rendering user-defined components. To render a component in React we can initialize an element with a user-defined component and pass this element as the first parameter to ReactDOM. render() or directly pass the component as the first argument to the ReactDOM. render() method.

How do you add a type to a class component React?

Typing Class Component Props and State To implement a React class component, the classes to extend are React. Component<P, S> or React. PureComponent<P, S> . You can read this syntax out loud as "Component of P" where P will be the props type substituted where referenced within the class definition.


1 Answers

I use the react-typescript bridge, which defines a base class which can be used from TypeScript:

class HelloMessage extends ReactTypescript.ReactComponentBase<{ name: string; }, {}> {
  render() {
    return React.DOM.div(null, 'Hello ' + this.props.name);
  }
}

Since the base class is generic, this.props is properly typed as { name: string; } in the example above.

like image 198
Douglas Avatar answered Sep 19 '22 04:09

Douglas