Search code examples
typescriptreact-intl

React-intl, use api with Typescript


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 seem to provide 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 it's 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!


Solution

  • The problem was due to the version of the typescript definition. When using @types/react-intl": "^2.2.0", it works like a charm.

    (edit) Few changes needed to make it work :

    //index.tsx
    <IntlProvider locale={`fr-FR`} messages={messages_fr}>
      <NameForm/>
    </IntlProvider>,
    
    //nameForm.tsx
    interface NameFormProps extends InjectedIntlProps {
      placeholder: string,
    }
    
    class NameForm extends React.Component<NameFormProps, {}> {
    
      render() {
        let namePlaceholder = this.props.intl.formatMessage({
           id: this.props.placeholder,
           defaultMessage: "name"
          });
    
        return (
          <form>
            <input placeholder={namePlaceholder} type="text"/>
          </form>
        );
    }
    
    export default injectIntl(NameForm);