Issue
Is there a best practice for having a function type with React prop types with TypeScript?
I assumed this would work but in fact it errored:
type Props = {
onClick: Function
};
const Submit = ({ onClick }: Props) => {
return (
<button type="button" onClick={onClick}>
click me
</button>
);
Following this thread I got it working, but it seems needlessly verbose: https://github.com/Microsoft/TypeScript/issues/20007
type Props = {
onClick: (...args: any[]) => any;
};
const Submit = ({ onClick }: Props) => {
return (
<button type="button" onClick={onClick}>
click me
</button>
);
Solution
Concerning Function
and best practices
Function
in practice has unsufficient type-safety, being the super-type of all functions. You better replace it with a function type - see the "Solutions" section down under.
In above example, Function
is not assignable to the more narrow onClick
function type, which causes the error at hand (Playground example).
In addition to mentioned issue, here is what TypeScript docs say about Function
:
This is an untyped function call and is generally best avoided because of the unsafe any return type. If need to accept an arbitrary function but don’t intend to call it, the type
() => void
is generally safer.
typescript-eslint has discarded Function
with the ban-types
rule, emitting following message with default configuration (see also here):
The
Function
type accepts any function-like value. It provides no type safety when calling the function, which can be a common source of bugs. If you are expecting the function to accept certain arguments, you should explicitly define the function shape.
Better solutions
React already comes with built-in event handler-types to handle common events.
For exampleclick
(Playground):
type Props = {
onClick: React.MouseEventHandler<HTMLButtonElement>
};
const Submit = ({ onClick }: Props) => <button onClick={onClick}> click </button>
A more general alternative is to use function types as follows:
type Props = {
onClick: (event: React.MouseEvent<HTMLElement>) => void
};
void
is more restrictive than any
. There is no chance to return a value in the callback by accident, which would be possible with any
.
In summary, we embrace typing capabilities of TypeScript instead of using Function
or any
.
The parameter now is known to be MouseEvent
and the return type void
, identifying it as a callback.
Related
Answered By - ford04
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.