Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How do I specify the type of a prop to refer to the type of another prop?

I’m not entirely sure how to ask this question, or what lingo to use, so I’m going to give this my best shot.

I want to write a component that works on an array of items, and will call a function render each item. I don’t want to specify the type of the item, or the arguments to the render function, but I do want to make sure they match. Here’s an example of what I’d like to do:

type MyComponentProps<ItemType = any> = {
    items: ItemType[];
    renderItem: (item: ItemType, index: number) => React.ReactElement;
};

const MyComponent = ({ items, renderItem }: MyComponentProps) => {
    return <div>{items.map((item, index) => renderItem(item, index))}</div>;
};

Taking this example component, I’d like to be able to use it like this:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

const App = () => {
    const items: string[] = ['foo', 'bar'];
    const renderItem = (item: string, index: number) => <div>{item}</div>;

    // This should be happy, and work fine
    return <MyComponent items={items} renderItem={renderItem} />;
}

However, I’d like this to fail:

const App = () => {
    const items: number[] = [1, 2];
    const renderItem = (item: string, index: number) => <div>{item}</div>;

    // This should generate a type error
    return <MyComponent items={items} renderItem={renderItem} />;
}

Should I be able to do something like this? I bet there is a way to make MyComponent generic, and then make a specific instance of that component where I need it for each ItemType I want to pass in. But I also think there might be a way to make the renderItem type refer to the items type somehow to make sure they all line up.

>Solution :

You were really close. All you need to do is to add a generic type to the MyComponent function.

type MyComponentProps<ItemType> = {
    items: ItemType[];
    renderItem: (item: ItemType, index: number) => React.ReactElement;
};

const MyComponent = <T,>({ items, renderItem }: MyComponentProps<T>) => {
    return <div>{items.map((item, index) => renderItem(item, index))}</div>;
};

T will be inferred as the type passed for items. If this does not match with item in the function parameters, an error is shown.

Playground

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading