Reputation: 1418
I am trying to understand and solve my own problem which is related to react components generic props.I have taken this code example from this article functional React components with TypeScript using generic props. Unfortunately, I couldn't reproduce the same in the Codesandbox and I get a ts error. Link to sandbox - link to sandbox
Typescript can't infer the right type for Tablle objects and throws an error
Property 'title' does not exist on type 'ObjectType'
I don't know what I am doing wrong, but seems like I just copied a part of the code from the article and it doesn't work.
import { render } from "react-dom";
import React, { PropsWithChildren } from 'react';
interface Props<ObjectType> {
objects: ObjectType[];
properties: {
key: keyof ObjectType,
title: string,
}[];
}
function Table<ObjectType,>(
{ objects, properties }: PropsWithChildren<Props<ObjectType>>,
) {
return (
<table>
<tbody>
{
objects.map(object => (
<div>{object.title}</div>
))
}
</tbody>
</table>
);
}
const PostsPage = () => {
const posts = [{id: 1, title: 'fsdf'}, {id: 2, title: '222fsdf'}];
return (
<div>
<Table
objects={posts}
properties={[
{
key: 'title',
title: 'Title'
},
]}
/>
</div>
);
};
const rootElement = document.getElementById("root");
render(<PostsPage />, rootElement);
Upvotes: 0
Views: 103
Reputation: 4014
Usually generics are expressed as <T>
, which can be any type. T
or (ObjectType
) doesn't guarantee anything about what properties it may have. If you try to access a property that TypeScript doesn't know about, it will complain.
If you want to assert that ObjectType
has a title property, you can do
type WithTitle = {
title: string;
};
<ObjectType extends WithTitle>
Or create a one-off object
<ObjectType extends { title: string }>
Though you can use <ObjectType>
as your template, I'd recommend sticking with <T>
, as it is the common convention, and you won't be tempted to think that T
is a defined type, while you may be looking around for the definition of ObjectType
.
Upvotes: 3