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

Function component props with typescript
Yes. Defining an interface separately, makes it reusable and easier to read and move. More on reddit.com
🌐 r/reactjs
18
3
January 18, 2023
React typescript. How can I get props type from a component?
This is not really clean and maybe there's a better way to do this, but you can up level the type definitions into a function using an HOC. You create a function that takes in the component you're using as your as prop, and give it the props you expect as a generic. It returns your custom link component that you want to use. // HOC definition: export interface CustomLinkProps { someSpecialProp: string; } function CustomLink(Link: FC) { return (props: CustomLinkProps & T) => ; } // Usage: // MyLink is now your component (ReactRouterLinkProps and // ReactRouterLink are assumed exports of react-router) const MyLink = CustomLink(ReactRouterLink); More on reddit.com
🌐 r/reactjs
2
3
October 8, 2021
reactjs - TypeScript React: Access component property types - Stack Overflow
Although this is not an explicit way of getting the type, it works for now (until the authors refactor the implementation). 2017-04-05T14:19:32.017Z+00:00 ... Unfortunately this no longer works because defaultProps now has a type of Partial

. 2018-03-09T10:34:55.263Z+00:00 ... @OliverJosephAsh that's true. If you really need that you can use module augmentation to extend react typings to put dummy type that would allow you to fetch prop types. Look here typescriptlang...

More on stackoverflow.com
🌐 stackoverflow.com
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
🌐
Bobby Hadz
bobbyhadz.com › blog › react-typescript-pass-function-as-prop
How to pass Functions as Props in React TypeScript | bobbyhadz
February 29, 2024 - Check out these resources: Type ... Another good way to figure out the type of a prop is to right-click on it and click "Go to Definition" in your IDE....
🌐
Undefinednull
undefinednull.com › posts › typescript-tips-getting-component-props-types-in-react
TypeScript Tips: Getting Component Props Types in React
September 10, 2021 - Luckily, React comes with some utility types for these situations. The generic type ComponentProps can be used for accessing any React component's props (works for both function component and class component).
🌐
Akhilaariyachandra
akhilaariyachandra.com › home › blog › get the type of a prop in a react component in typescript
Get the type of a prop in a React component in TypeScript | Akhila Ariyachandra
March 3, 2023 - import CustomComponent from "component-library"; import type { ComponentProps } from "react"; type PropType = ComponentProps<typeof CustomComponent>["propName"];
🌐
Pluralsight
pluralsight.com › tech insights & how-to guides › tech guides & tutorials
Defining Props in React Function Component with Typescript | Pluralsight
New customers get 50% off. Use code TECHMARCH50 at checkout. ... 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.
Find elsewhere
🌐
Oida
oida.dev › typescript-react › prop-types
TypeScript and React: Prop Types
July 17, 2019 - All you need is the InferProps generic: import PropTypes, { InferProps } from "prop-types"; export function Article({ title, price }: InferProps<typeof Article.propTypes>) { return ( <div className="article"> <h1>{title}</h1> <span>Priced at ...
🌐
Reddit
reddit.com › r/reactjs › react typescript. how can i get props type from a component?
r/reactjs on Reddit: React typescript. How can I get props type from a component?
October 8, 2021 -

Hi,all.

I want to defined a Link component that has an as props. For example, using react router link component. <Link as={ReactRouterLink} to="/">Page</> . In this case, even I know the types of react router link, for example to props, but I don't want to define it on the Link. Is there a way to define the types of Link that can extend the type from as component?

🌐
DEV Community
dev.to › amanhimself › prop-types-in-react-and-typescript-1kph
Prop types in React and TypeScript - DEV Community
June 28, 2021 - PropTypes package offers InferProps that enables to infer the types for an existing prop-type definition on a component. It uses the @types/prop-types package to create type definitions.
Top answer
1 of 5
574

2019: noticed all answers above are quite outdated so here is a fresh one.


Lookup type

With newer TS versions you can use lookup types.

type ViewProps = View['props']

Despite being very convenient, that will only work with class components.


React.ComponentProps

The React typedefs ship with an utility to extract the type of the props from any component.

type ViewProps = React.ComponentProps<typeof View>

type InputProps = React.ComponentProps<'input'>

This is a bit more verbose, but unlike the type lookup solution:

  • the developer intent is more clear
  • this will work with BOTH functional components and class components

All this makes this solution the most future-proof one: if you decide to migrate from classes to hooks, you won't need to refactor any client code.

2 of 5
41

Starting with TypeScript 2.8, you can use conditional types, e.g. given:

interface MyComponentProps { bar: string; }
declare const MyComponent: React.Component<MyComponentProps>;

interface MyComponentClassProps { bar: string; }
declare const MyComponentClass: React.ComponentClass<MyComponentClassProps>;

interface MyStatelessComponentProps { bar: string; }
declare const MyStatelessComponent: React.StatelessComponent<MyStatelessComponentProps>;

We can define these helpers:

type GetComponentProps<T> = T extends React.ComponentType<infer P> | React.Component<infer P> ? P : never

And use them like so:

// $ExpectType MyComponentProps
type MyComponentPropsExtracted = GetComponentProps<typeof MyComponent>

// $ExpectType MyComponentClassProps
type MyComponentClassPropsExtracted = GetComponentProps<typeof MyComponentClass>

// $ExpectType MyStatelessComponentProps
type MyStatelessComponentPropsExtracted = GetComponentProps<typeof MyStatelessComponent>

Update 2018-12-31: this is now available in the official React typings via React.ComponentProps.

🌐
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 - function App() { const handleSubmit = ( values ) => { console.log(values); }; return ( <div> <SignUpForm onSubmit={handleSubmit} /> </div> ); } If you don't have an option "noImplicitAny": false, it occurs an error. For avoiding this problem, you can repeat the type of the onSubmit. If you just repeated like this, you'll have to keep up-to-date depending on the onSubmit prop. It would bother you. In this case, you can get the field type of the interface using brackets.
🌐
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> ); }
🌐
amanhimself.dev
amanhimself.dev › blog › prop-types-in-react-and-typescript
Prop types in React and TypeScript | amanhimself.dev
June 28, 2021 - PropTypes package offers InferProps that enables to infer the types for an existing prop-type definition on a component. It uses the @types/prop-types package to create type definitions.
🌐
Bonsaiilabs
bonsaiilabs.com › typescript-prop-type-checking
How to perform prop type checking in a Function Component - React with TypeScript? - bonsaiilabs
Since date is optional field, we don't get any errors. On the other hand if I pass amount as string instead of a number, it will show you the error. So this is how you can have strongly typed props inside your function component. That's all I wanted to cover in this video, let us know if there is a specific topic you would like to be covered in TypeScript...
🌐
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.
🌐
TypeScript
typescriptlang.org › docs › handbook › utility-types.html
TypeScript: Documentation - Utility Types
TypeScript provides several utility types to facilitate common type transformations. These utilities are available globally. ... This type is meant to model operations like await in async functions, or the .then() method on Promises - specifically, the way that they recursively unwrap Promises. ... Constructs a type with all properties ...
🌐
Total TypeScript
totaltypescript.com › tips › write-your-own-propsfrom-helper-to-extract-props-from-any-react-component
Write your own 'PropsFrom' helper to extract props from any React component | Total TypeScript
type PropsFrom<TComponent> = TComponent extends React.FC<infer Props> ... So this now is working both with react functional components and class components. 0:00 A common pattern in TypeScript is to create type helpers that allow you to extract types from things that are not types.
Published   May 30, 2023
🌐
Catchts
catchts.com › react-props
Handle Props in React in TypeScript
@captain-yossarian TypeScript blog, fully dedicated to static typings and type safety
🌐
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>