7

I'm getting the error below:

Type '(props: PropsWithChildren<{ amount: number; }>) => string' is not assignable to type 'FC<{ amount: number; }>'.
  Type 'string' is not assignable to type 'ReactElement<any, any> | null'.ts(2322)

when using the below typescript function, not understanding the issue here, any help is appreciated, thanks!

Code is below,

const MoneyAmount: React.FC<{amount : number}> = (props) => {
    return (
        new Intl.NumberFormat("en-US", {
            style: "currency",
            currency: "USD", 
            maximumFractionDigits: 4
        }).format(props.amount))
}

export default MoneyAmount  ;
1
  • please use triple backticks if you want to embed the piece of code. See how I did it in my answer Commented Sep 15, 2021 at 6:16

2 Answers 2

4

Take a look on FC type:

   type FC<P = {}> = FunctionComponent<P>;

    interface FunctionComponent<P = {}> {
        (props: PropsWithChildren<P>, context?: any): ReactElement<any, any> | null;
        propTypes?: WeakValidationMap<P>;
        contextTypes?: ValidationMap<any>;
        defaultProps?: Partial<P>;
        displayName?: string;
    }

This function returns ReactElement<any, any> | null.

WHich in turn is just a jsx with set of properties.

    interface ReactElement<P = any, T extends string | JSXElementConstructor<any> = string | JSXElementConstructor<any>> {
        type: T;
        props: P;
        key: Key | null;
    }

All you need to do is to wrap your return value into a span:

const MoneyAmount: React.FC<{ amount: number }> = (props) => {
  const text = new Intl.NumberFormat("en-US", {
    style: "currency", currency: "USD", maximumFractionDigits: 4
  })
    .format(props.amount)


  return <span>{text}</span>
}

Let's try to use it without FC:

import React from 'react'

const MoneyAmount = (props: { amount: number }) => {
  return (
    new Intl.NumberFormat("en-US", {
      style: "currency",
      currency: "USD",
      maximumFractionDigits: 4
    }).format(props.amount))
}

// Its return type 'string' is not a valid JSX element.
const x = <MoneyAmount amount={42} />

Hence, string is just invalid JSX

Sign up to request clarification or add additional context in comments.

Comments

4

You can wrap your string in <Fragment>, and it will pass typecheck.

The issue is that React is expecting a ReactElement type, and string isn't one of those. Fragment lets you return strings and arrays to components.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.