brielov
brielov

Reputation: 1947

How to create a type that takes an object and returns a modified version?

I need to type a function that takes an object and return a modified object like so:


const data = {
  email: '[email protected]',
}

// This type is where I have trouble
type WrappedInput<T, K extends keyof T> = { [key: K]: { set: T[K] } }

function toInput<T = unknown>(data: T): WrappedInput<T> {
  return {
    email: {
      set: data.email
    }
  }
}

Every key should be wrapped under a set key.

Upvotes: 1

Views: 53

Answers (1)

jcalz
jcalz

Reputation: 327634

This is a relatively straightforward mapped type:

type WrappedInput<T> = { [K in keyof T]: { set: T[K] } }

Note the in operator in the type definition, indicating that this is a mapped type instead of a string index signature. The above mapped type iterates over all the keys K in the union of keys keyof T and operates on them individually.

Then your implementation could possibly look like this:

function toInput<T>(data: T): WrappedInput<T> {
  return Object.fromEntries(
    Object.entries(data).map(([k, v]) => [k, { set: v }])
  ) as any;
}

(assuming your environment has Object.fromEntries() and Object.entries()).

And we can test it:

const inputData = toInput(data);
console.log(inputData.email.set.toUpperCase()) // [email protected]

Looks like what you wanted.

Playground link to code

Upvotes: 4

Related Questions