функциональные компоненты реагирования с использованием типографского текста с использованием общих реквизитов

#reactjs #typescript #typescript-generics

Вопрос:

Я пытаюсь понять и решить свою собственную проблему, связанную с общими реквизитами компонентов react.Я взял этот пример кода из этой статьи функциональные компоненты реакции с машинописным текстом с использованием общих реквизитов. К сожалению, я не смог воспроизвести то же самое в Codesandbox, и я получаю ошибку ts. Ссылка на песочницу — ссылка на песочницу

Typescript не может определить правильный тип объектов Tablle и выдает ошибку

Свойство ‘title’ не существует для типа ‘ObjectType’

Я не знаю, что я делаю не так, но, похоже, я просто скопировал часть кода из статьи, и это не работает.

 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);
 

Ответ №1:

Обычно дженерики выражаются как <T> , которые могут быть любого типа. T или ( ObjectType ) ничего не гарантирует о том, какими свойствами он может обладать. Если вы попытаетесь получить доступ к свойству, о котором TypeScript не знает, он будет жаловаться.

Если вы хотите утверждать, что ObjectType у вас есть свойство title, вы можете сделать

 type WithTitle = {
  title: string;
};

<ObjectType extends WithTitle>
 

Или создайте одноразовый объект

 <ObjectType extends { title: string }>
 

Хотя вы можете использовать <ObjectType> в качестве шаблона, я бы рекомендовал придерживаться <T> , поскольку это общепринятое соглашение, и у вас не возникнет соблазна думать, что T это определенный тип, в то время как вы можете искать определение ObjectType .