0

I would like to type the following function:

carryOver = <T extends Record<string, any>>(fun: (obj: T) => Record<string, any>) => (obj: T) => Object.assign({}, obj, fun(obj))

Such that I can do e.g.:

const makeGreeting = ({name, title}) => ({greeting: `Hello ${title} ${name}`})
const person = {name: "Thomas", title: "Dr."}
const personWithLabel = carryOver(makeGreeting)(person) 
// { name: "Thomas", title: "Dr.", greeting: "Hello Dr. Thomas" }

I.e. carryOver() accepts a function that takes in an object A, destructures it, and returns a new object B, with properties computed from the destructured properties of A. carryOver() then combines the objects together, so we end up with augmented object with properties from both A and B.

How do I type carryOver() so that the type of the output has both the props of A and B?

1
  • Does this approach meet your needs? If so I'll write up an answer explaining; if not, what am I misssing? Commented Jan 19, 2023 at 4:02

1 Answer 1

1

Here's my implementation:

const carryOver = <A extends object, B extends object>(a: A, fn: (a: A) => B)
    => Object.assign({}, a, fn(a));

const makeGreeting = (a: { name: string, title: string })
    => ({greeting: `Hello ${a.name} ${a.title}`});
const person = { name: "Thomas", title: "Dr." };
const personWithLabel = carryOver(person, makeGreeting);

The return type is correctly inferred from the carryOver() function as {} & A & B.

Sign up to request clarification or add additional context in comments.

1 Comment

Oh yep, type inference works perfectly for this, thanks that makes things a lot easier!

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.