Preserve functions typing when augmenting an object in Typescript

Viewed 45

I need to perform some transformations on a typescript object while being able to preserve it's full shape.

So, I have an object:

const simpleObject = {
  one: () => ({}),
  two: (a: number) => ({ a }),
};

type SimpleObject<K, V> = {
  [P in keyof K]: V; // Not sure how to type V correctly to be a function that takes any arguments and outputs an object
};

where the values are generic functions that output an object.

I need to perform some transformations on the object, so that:

type AugmentedObject<K, V> = {
  [P in keyof K]: V; // again, typing of V is not correct here, it should be a generic function that outputs an object
};

function augmentObject<K, V>(simpleObject: SimpleObject<K, V>): AugmentedObject<K, V> {
  // perform some transformation
  // ...
  return simpleObject;
}

augmentObject(simpleObject).one; // the type should resolve to a () => object
augmentObject(simpleObject).two; // the type should resolve to (a: number) => object

I cannot figure out how to maintain the correct typing for one or two as I can't figure out how to generically pass a function

1 Answers

I'not sure this is the solution you're looking for. Though the final types are just the exact shape you're expecting them to be.


const simpleObject = {
  one: () => ({}),
  two: (a: number) => ({ a }),
};

type SimpleObject
  = { [K in string | number | symbol]: (...args: any[]) => object }

function augmentObject<T extends SimpleObject>(simpleObject: T): T {
  // perform some transformation
  // ...
  return simpleObject;
}

const a = augmentObject(simpleObject)

type One = typeof a.one  // type One = () => {}
type Two = typeof a.two  // type Two = (a: number) => { a: number }

TS playground

Related