Vanquish46
Vanquish46

Reputation: 534

TS property doesn't exist on type defined by generic

I have a type Columns that contains information used to render a table:

export type Columns = {
  header: React.ReactNode;
  cellContent: <T>(content: T, rowIndex: number) => React.ReactNode;
  ...
}

I then define a Columns[] array in a component that is going to render some data. You can see an example here:

{
  header: 'Site name',
  cellContent: <Equipment,>(equipment: Equipment, rowIndex: number) => {
    return (
      <div className={styles.equipmentNameContainer}>{equipment.title}</div>
    );
  },
},

However, I get an error that property 'title' does not exist on type 'Equipment', yet it does as you can see here:

export type Equipment = {
  _entity: ResourceType.EQUIPMENT;
  id: number;
  title: string;
  ...
}

I noticed that the import of the Equipment type is grayed out in VS Code, and indeed if I delete the import I get no complain about Equipment type not existing, so clearly I am defining something wrong and have somehow created a 'locally scoped type' for Equipment.

What do I need to do to make the content parameter generic and specified by the cellContent key when making my columns array?

I have tried googling and have not found anything about this

EDIT: sandbox available here (https://codesandbox.io/s/typescript-playground-export-ibhf7?fontsize=14&hidenavigation=1&theme=dark) that reflects the comment below but still has an issue

Upvotes: 0

Views: 773

Answers (1)

Drag13
Drag13

Reputation: 5988

You can solve this with next ways:

  • Directly say TS the T will be Equipment base class. Not the best option, because you loose flexibility.
import { Equipment } from "./Equipment";

type Columns = {
  header: string;
  cellContent: <T extends Equipment>(content: T, rowIndex: number) => string;
};

const columns: Columns[] = [
  {
    header: "Site name",
    cellContent: (equipment: Equipment, rowIndex: number) => {
      return equipment.title;
    }
  }
];
  • Add T as generic to the Type, which is much better from my side:
type Columns<T> = {
  header: string;
  cellContent: (content: T, rowIndex: number) => string;
};

const columns: Columns<Equipment>[] = [
  {
    header: "Site name",
    cellContent: (equipment: Equipment, rowIndex: number) => {
      return equipment.title;
    }
  }
];

Upvotes: 2

Related Questions