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 example click (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

Typescript: How to define type for a function callback (as any function type, not universal any) used in a method parameter

Answer from ford04 on Stack Overflow
Top answer
1 of 2
68

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 example click (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

Typescript: How to define type for a function callback (as any function type, not universal any) used in a method parameter

2 of 2
10

You can simply write it like this, which prevents any and is more telling. Especially for custom functions:

Interface Props { onClick: (e: Event) => void; }

This will tell the calling component, what onClick will expect and what the parameters are.

Hope this helps. Happy coding.

🌐
React TypeScript Cheatsheets
react-typescript-cheatsheet.netlify.app › typing component props
Typing Component Props | React TypeScript Cheatsheets
(common) */ objArr: { id: string; title: string; }[]; /** any non-primitive value - can't access any properties (NOT COMMON but useful as placeholder) */ obj2: object; /** an interface with no required properties - (NOT COMMON, except for things like `React.Component<{}, State>`) */ obj3: {}; /** a dict object with any number of properties of the same type */ dict1: { [key: string]: MyTypeHere; }; dict2: Record<string, MyTypeHere>; // equivalent to dict1 /** function that doesn't take or return anything (VERY COMMON) */ onClick: () => void; /** function with named prop (VERY COMMON) */ onChang
Discussions

How to pass function as a prop in react typescript
I am learning typescript with react and I occurred problem. I tried to pass function as a prop from my App component to child component named DataForm. but I got an error: Type '(f: any) => any... More on stackoverflow.com
🌐 stackoverflow.com
In React v19, ref is now a prop. But how it would be using typescript?
React.RefObject or React.MutableRefObject More on reddit.com
🌐 r/react
11
8
June 5, 2024
Can Typescript for React props be terser?
Destructing is pretty common convention, but you don’t have to do it. If the repetition bothers you, you can do function GameList(props: Props) { // reference everything via props.[x] Depending on your component though needing to add “props.” everywhere can make things pretty unnecessarily cluttered. More on reddit.com
🌐 r/typescript
18
6
April 30, 2024
Complex type check based on a prop
When component is not specified, typescript does not know what the value of the param C should be. It uses the value you specify in the extends. This default value allows any arguments, so any arguments end up being allowed. You can set an default type argument and set to it undefined, so it does not allow any extra arguments You need a small change to FieldProp so function Field({component: Component, name, ...props}: FieldProps) { TS playground More on reddit.com
🌐 r/typescript
6
3
February 8, 2024
🌐
Pluralsight
pluralsight.com › tech insights & how-to guides › tech guides & tutorials
Defining Props in React Function Component with Typescript | Pluralsight
Learn how to define props for function components in React projects with Typescript. We cover several different methods, including destructuring and React.FC. ... This guide will help you properly define the props entering your function components. You'll also learn when defining props as a class or interface type is best and how to provide default values to optional props.
🌐
Carl Rippon
carlrippon.com › different-ways-to-strongly-type-function-component-props-with-typescript
Different ways to strongly-type function component props with TypeScript
April 7, 2020 - This means our component now accepts props such as maxLength and placeholder. Alternatively we can use a type alias and intersection to achieve the same effect: ... A comprehensive guide to building modern React applications with TypeScript. Learn best practices, advanced patterns, and real-world development techniques.
🌐
DEV Community
dev.to › lico › react-ts-dont-repeat-the-type-when-you-pass-functions-as-props-use-their-types-5h6h
React TS: Don't repeat the type when you pass functions as props, use their types. - DEV Community
August 21, 2022 - export interface SignUpFormProps { onSubmit?: (values: { username: string; nickname: string; password: string; }) => void; } export const SignUpForm = ({ onSubmit }: SignUpFormProps) => { const [values, setValues] = useState({ username: "", nickname: "", password: "", }); const handleChange: React.ChangeEventHandler<HTMLInputElement> = (e) => { setValues((prevValues) => ({ ...prevValues, [e.target.name]: e.target.value, })); }; const handleSubmit: React.FormEventHandler = (e) => { e.preventDefault(); onSubmit?.(values); }; return ( <form onSubmit={handleSubmit} style={{ display: "flex", flexDi
🌐
Bobby Hadz
bobbyhadz.com › blog › react-typescript-pass-function-as-prop
How to pass Functions as Props in React TypeScript | bobbyhadz
The example shows how we can right-click on the style prop of an element and figure out that its type is CSSProperties or undefined. If you need to pass CSS styles as props in React TypeScript, check out my detailed guide.
Find elsewhere
🌐
Oida
oida.dev › typescript-react › prop-types
TypeScript and React: Prop Types
July 17, 2019 - E.g. when you set a prop type to isRequired, but add a defaultProp for it, TypeScript understands that this becomes optional. Article.propTypes = { title: PropTypes.string.isRequired, price: PropTypes.number.isRequired }; Article.defaultProps = { price: 20 }; ... Compared to other ways of defining components like the FunctionComponent type, InferProps only deals with properties, not with the component itself.
🌐
amanhimself.dev
amanhimself.dev › blog › prop-types-in-react-and-typescript
Prop types in React and TypeScript | amanhimself.dev
June 28, 2021 - TypeScript comes with a type keyword. It can be used to define prop types without using the prop-types package. type Props = { color: string; }; function FavoriteColor({ color }: Props) { return <h2>My favorite Color is {color} </h2>; }
🌐
Akos Komuves
akoskm.com › how-to-type-react-props-with-typescript
How to type React Props with TypeScript | Akos Komuves
January 6, 2023 - Another, even more straightforward way to type React props is to specify the object type inside the function's signature. Below we're simply telling react that this object has a specific type: Now let's see the differences between the two regarding type safety. When using React.FC, if you define a default value with a different type than the type in Props, it'll merge the two types and assign that as the new type for the prop. You might expect the below code to fail the TypeScript compilation, but it won't.
🌐
React
legacy.reactjs.org › docs › typechecking-with-proptypes.html
Typechecking With PropTypes – React
To run typechecking on the props for a component, you can assign the special propTypes property: import PropTypes from 'prop-types'; class Greeting extends React.Component { render() { return ( <h1>Hello, {this.props.name}</h1> ); } } Greeting.propTypes = { name: PropTypes.string }; In this example, we are using a class component, but the same functionality could also be applied to function components, or components created by React.memo or React.forwardRef.
🌐
TypeScript
typescriptlang.org › docs › handbook › 2 › functions.html
TypeScript: Documentation - More on Functions
If we want to describe something callable with properties, we can write a call signature in an object type: ... Note that the syntax is slightly different compared to a function type expression - use : between the parameter list and the return type rather than =>. JavaScript functions can also be invoked with the new operator. TypeScript ...
🌐
Ben Ilegbodu
benmvp.com › blog › react-prop-types-with-typescript
React Prop Types with TypeScript | Ben Ilegbodu
NOTE: PropTypes.shape() allows for additional properties outside of those to be included in the object, so technically the equivalent TypeScript type is an index type. But generally, when folks use PropTypes.shape() they really mean PropTypes.exact(). ... Example.propTypes = { onClick: PropTypes.func, onChange: PropTypes.func, onSelect: PropTypes.func, } ... interface Props { onClick: () => void onChange: (val: string) => void onSelect: (id: string, val: number) => void } NOTE: As you can see, function prop types do not define their interface, while TypeScript functions have an explicit definition of their params and return value.
🌐
DEV Community
dev.to › captainyossarian › how-to-type-react-props-as-a-pro-2df2
How to type React props as a pro in TypeScript - DEV Community
July 25, 2021 - So, lets merge our function union with less specific overload · // credits goes to https://stackoverflow.com/a/50375286 type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ( k: infer I ) => void ? I : never; type Overload<PropsUnion> = & UnionToIntersection<PropsUnion[FnProps<PropsUnion>]> & ParametersUnion<PropsUnion> // & ((a: A['data']) => string) // & ((a: B['data']) => number) // & ((a: C['data']) => number) // & ((a: string | number | number[]) => string | number) type Result3 = Overload<Props>
🌐
React
react.dev › learn › typescript
Using TypeScript – React
Writing TypeScript with React is very similar to writing JavaScript with React. The key difference when working with a component is that you can provide types for your component’s props. These types can be used for correctness checking and providing inline documentation in editors. Taking the MyButton component from the Quick Start guide, we can add a type describing the title for the button: ... function MyButton({ title }: { title: string }) { return ( <button>{title}</button> ); } export default function MyApp() { return ( <div> <h1>Welcome to my app</h1> <MyButton title="I'm a button" /> </div> ); }
🌐
React TypeScript Cheatsheets
react-typescript-cheatsheet.netlify.app › function components
Function Components | React TypeScript Cheatsheets
These can be written as normal functions that take a props argument and return a JSX element. // Declaring type of props - see "Typing Component Props" for more examples type AppProps = { message: string; }; /* use `interface` if exporting so that consumers can extend */ // Easiest way to declare a Function Component; return type is inferred.
🌐
DhiWise
dhiwise.com › post › react-function-components-and-typescript-mastering-the-advanced-techniques
React Function Components and Advanced TypeScript Techniques
April 30, 2025 - This approach helps to catch errors early and create more robust components. ... Default props in React are values that are used if the prop is not explicitly provided. TypeScript can define the type of the default props object.
🌐
DEV Community
dev.to › anavalo › enforcing-prop-combinations-with-typescript-function-overloading-in-react-4ob2
Conditional React props with TypeScript Function Overloading - DEV Community
October 20, 2023 - The component should only accept an icon prop if a handleClickIcon function is also present. ... This won't enforce that handleClickIcon is relevant only when you've got an icon. A better strategy is to use function overloading in TypeScript: type CommonProps = { text: string }; type IconAndClickProps = { icon: JSX.Element; handleClickIcon: () => void }; // function overloading export function Button(props: CommonProps): JSX.Element; export function Button(props: CommonProps & IconAndClickProps): JSX.Element; export function Button(props: CommonProps & IconAndClickProps): JSX.Element { // ...your button implementation }