TypeScript .map: Adding new property to array of objects. Property does not exist on type

Viewed 352
type Cat = { name: string; fur: "brown" | "white" };

const addOrigin = (animals: Cat[], origin: "Italy" | "France") =>
    animals.map((animal) => (animal.origin = origin)); // animal.origin throws error (see below)

throws

Property 'origin' does not exist on type 'Cat'.ts(2339)

Is there a way to leave the Cat type as it is and to implement something like OriginAddedCat into addOrigin function?

1 Answers

For Array.map the return value of the passed function is used to construct the elements of the new array. In your case this would be,

type Cat = { name: string; fur: "brown" | "white" };

const addOrigin = (animals: Cat[], origin: "Italy" | "France") =>
    animals.map((animal) => ({ ...animal, origin }));
    

The return type of addOrigin will now include the origin property.

You could let type inference do the rest, but if you want to define the OriginAddedCat then you could either do,

interface Cat {
    name: string;
    fur: "brown" | "white";
}

interface OriginAddedCat extends Cat {
   origin: "Italy" | "France";
}

or

type OriginAddedCat = Cat & { origin: "Italy" | "France" };

or

type OriginAddedCat = ReturnType<typeof addOrigin>[number];
Related