1
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
  • 1
    That's not a mapping. To use Array.map the expectation is that the selector function has no side effects. This is not the case here, because your code (if it worked) would mutate values that already exist. If you want to perform side-effects over your existing array, you're better off using Array.forEach, but be warned that mutation of existing data can make code much harder to understand. Use Array.map, but don't mutate what passes thru the mapping func... construct an array of new objects (as per @JamesElderfield's answer) Commented Dec 3, 2021 at 12:14

1 Answer 1

4

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];
Sign up to request clarification or add additional context in comments.

1 Comment

yeah, thank you. i feel pretty dumb after asking this question, it was a long working day that day :D

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.