So I just encountered a problem where I want to make a better type checking in a props of a React component. It’s about one prop takes an array of certain type X, and in another prop : callback, this type X needs to be the parameter of the callback. Let’s see how to do that in TypeScript.

1. Declare type for the props

1

2

3

4

interface IDropDownProps<T> {

items: Array <T>;

getItemProps: ( item: T, index: number ) => object;

}



T means here we take a generic type T and use it through this IDropDownProps :

The items is an array of type T . the first parameter of getItemProps takes type T as well.

In order to share type between these two props , we need to have this type T declared at the interface level, this is why wen have that IDropDownProps<T> .

Now things become interesting because when you apply this IDropDownProps<T> to a component, you MUST declare what this T is.

2. Declare the component

Now we need to declare the React component which takes this IDropDownProps as its props .

2.1 For a class component

it’s just as easy as class DropDown<T> extends React.Component<IDropDownProps<T>> .

2.2 For a function component

With the introduction of hooks , function component will be the future of React. and remember the name function component , now it’s been unified to this name compare to the stateless functional component , even in the latest version of @types/react , now you can use React.FC than React.SFC .

1

2

3

function DropDown < T >( { items, getItemProps }: IDropDownProps<T> ) {



}



Don’t know how to use it with a component been declared like this:

1

const DropDown: React.FC<IDropDownProps<T>>;



Feel free to comment if you know how.

3. Render this component with type T

We just declared the component, now we need to use it, the problem is, when we use a component, most of the time, we use JSX syntax. With Typescript 2.9, generic type in JSX syntax is possible.

So, you just use it like this:

1

2

3

<DropDown<string>

items={provinces} getItemProps={getItemProps} /></DropDown<string

>



Now, if you pass a wrong callback like this:

1

2

3

const getItemProps = ( item: number ) => {

text: item;

};



The compiler will complain that the expected type for item is string where you declare it as a number .

4. End

Hope it helps. :)

Thanks for reading!

Follow me (albertgao) on twitter, if you want to hear more about my interesting ideas.