React-intl, use api with Typescript

Emarco picture Emarco · Nov 24, 2016 · Viewed 13.3k times · Source

I would like to use the formatMessage function of the react-intl API to insert a message as placeholder, but I can't figure out the right way to access this function.

Here is a simplified version of what I have :

//index.tsx
<IntlProvider locale={`fr-FR`} messages={messages_fr}>
    <NameForm/>
</IntlProvider>,

//nameForm.tsx
interface NameFormProps {
   intl?: InjectedIntlProps,
}

export default injectIntl(NameForm);

class NameForm extends React.Component<NameFormProps, {}> {

render() {
    let namePlaceholder = this.props.intl.formatMessage(
        {id: "NAME_PLACEHOLDER",
        defaultMessage: "name"
    });

    return (
        <form>
            <input placeholder={namePlaceholder} type="text"/>
        </form>
    );
}

I used InjectedIntlProps as type of the intl prop, because IntlShape didn't seems to offer a formatMessage method.

I Added a ? to the intl prop because I kept having a "Property 'intl' is missing" (but isn't injectIntl supposed to return a component without this prop ?)

Now it compiles, but when running I get an error ("Cannot read property 'displayName' of undefined" I guess because the default export doesn't have an explicit name).

I feel I'm not going in the right direction, but can't find any example of a typescript/react-intl project.

Thanks for your help !

Answer

Braden Walters picture Braden Walters · Nov 8, 2017

While working with the same problem, I found that neither including InjectedIntlProps as a member, as mentioned in the question, nor extending from it, as mentioned in another answer, satisfies the type checker. When extending from InjectedIntlProps, the call to injectIntl checked, but using the resulting component in JSX expected me to provide an intl property. The following strategy resolved this though:

    interface NameFormProps {
        // Include all custom properties here.
    }

    class NameForm extends React.Component<NameFormProps & InjectedIntlProps, {}> {
        // Class body.
    }

    export default injectIntl(NameForm);