Zheng
Zheng

Reputation: 76

Modify the arguments in an object of functions with Typescript and Proxy

I'm trying to modify an object generated by a third part for a better developer experience as the some of the arguments in the generated object are no longer needed/can be set by default where it's been used. Though I still want to keep the IntelliSense in typescript when my hook is called to give the suggestion of available methods in that object.

type ObjectFunction<Type> = Type extends (_: { prop: infer MessageType }, __: infer CallbackType) => infer Return
  ? (prop?: MessageType, callback?: CallbackType) => Return
  // trying to simplify the argument above
  : never;

type NewObjectType<Type> = {
  [Property in keyof Type as ObjectFunction<Type[Property]> extends never ? never : Property]: ObjectFunction<
    Type[Property]
  >;
};

and below is me trying to proxy it out in my hook

return new Proxy<NewObjectType<typeof originalObj>>(
    { ...originalObj },
    // typescript will error above as the shape is different thru the NewObjectType and the orignalObj
    {
      get(target, method) {
        if (typeof method === "string" && target.hasOwnProperty(method)) {
          return target[method as keyof NewObjectType<typeof originalObj>];
        }
      },
    },
  );

Here is an example of what i want to achieve

originalObj = {
  method1: (arg: {prop: string}, callback?: ()=> void) => void
  method2: (arg: {prop: string}, callback?: ()=> void) => void
  ...
}

into below

newObj = {
  method1: (prop?: string, callback?: ()=> void) => void
  method2: (prop?: string, callback?: ()=> void) => void
  ...
}

Upvotes: 0

Views: 99

Answers (1)

Bergi
Bergi

Reputation: 664579

No reason for a proxy here. And it seems that your proxy isn't working, it returns the original methods instead ones that take the prop string directly.

I would recommend to write simply

const newObj = {} as NewObjectType<typeof originalObj>;
for (const name in originalObj) {
  newObj[name] = (prop, callback) => originalObj[name]({prop}, callback);
}
return newObj;

Upvotes: 1

Related Questions