Property 'id' does not exist on type 'T'.(2339) Typescript Generics error

Viewed 11156

I have a function called updateArrayOfObjects which updates the object in the array. I am passing a generic type to this function like below:

interface OtherIncomeSource {
  id?: string;
  incomeDescription?: string;
  amount?: number;
}

const otherIncomes = [
          {
            id: "#6523-3244-3423-4343",
            incomeDescription: "Rent",
            amount: 100
          },
          {
            id: "#6523-3244-3423-4343",
            incomeDescription: "Commercial",
            amount: undefined
    }
]

const updateArrayOfObjects = <T>(arrayOfObjects: T[], newObject: T, deleteObject: boolean = false): T[] => {
    const newArrayOfObjects = arrayOfObjects.slice();

  let index = newArrayOfObjects.findIndex((obj: T) => obj.id === newObject.id)
  if(deleteObject) {
    newArrayOfObjects.splice(index, 1);
  } else {
    if (index === -1) {
      newArrayOfObjects.push(newObject);
    } else {
      newArrayOfObjects[index] = newObject;
    }
  }

  return newArrayOfObjects
}

const newData = updateArrayOfObjects<OtherIncomeSource>(otherIncomes, {id: '1233', incomeDescription: 'agri', amount: 5000})

I am getting an error at the below mentioned line when accessing idsaying "Property 'id' does not exist on type 'T'.(2339)":

let index = newArrayOfObjects.findIndex((obj: T) => obj.id === newObject.id)

Below is the typescript playground link for a complete environment of this issue and in here the error is highlighted in red: Example in Typescript Playground

2 Answers

You need to provide a constraint for your generic type as follows: <T extends { id?: string }>

Update the line const updateArrayOfObjects = <T>(arrayOfObjects: T[], newObject: T, deleteObject: boolean = false): T[] => {

to const updateArrayOfObjects = <T extends { id?: string }>(arrayOfObjects: T[], newObject: T, deleteObject: boolean = false): T[] => {

I had a more complex case where the above answer didn't work for me.

This is what worked for me:

type SimpleTableProps<T> = {
  data: Array<T & { id?: number }>;
  ...
};

const SimpleTable = <T,>(props: SimpleTableProps<T>): JSX.Element => {...}

Related