I have two functions with the same signature(supposedly), but it seems they are not the same from the compiler's view: the todos
in the arrow function is of Todo[]
type, while the todos
in the NON-arrow function is of any
type.
I must be missing something here.
interface TodoState {
todos: Todo[]
}
//no error
const arrowFunc: React.FC<TodoState> = ({ todos }) => { }
//error: binding element 'todos' implicitly has an 'any' type.ts(7031)
function nonArrow({ todos }): React.FC<TodoState> {}
const arrowFunc: React.FC<TodoState> = ({ todos }) => {}
// ^ function type ^ props ^ function return value
This declares a function, and the type of that function conforms to React.FC<TodoState>
. Which is to say the functional component accepts props like TodoState
, plus a children
property and returns JSX.
function nonArrow({ todos }): React.FC<TodoState> {}
// ^ function return value
But this says something different. nonArrow
is a function that does not return JSX, it returns a functional component.
The first form types the function as React.FC<TodoState>
, and the second form types the return value of the function as React.FC<TodoState>
.
There is no syntax to assign an existing function type with the function
keyword. Typically if you want a functional component to be typed as such, you use the first form.
But that's only helpful if you need children
as a prop. Otherwise, this simple construct works great for most functional components:
function MyFuncComp({ propName }: Props) {
return <h1>{propName}</h1>
}
// called like this:
<MyFuncComp propName='foo'/>
All you need to type most of the time is the props, and then just return some JSX and Typescript+React figure the rest out for you.
Or if your component takes children, it's common to do:
interface Props {
propName: string
}
const MyFuncComp: React.FC<Props> = ({ propName, children }) => {
return <div>
<h1>{propName}</h1>
{children}
</div>
}
// called like this:
<MyFuncComp propName='foo'>
<p>some children</p>
</MyFuncComp>