首页 > 解决方案 > Typescript 代理函数以扩展接受的参数或其类型

问题描述

我正在尝试创建一个类,该类部分充当其他类的代理包装器,允许修改其他类方法并接受额外的参数或更改它们的类型。

假设我有:

class MainClass {
  myMethod(txt: string) {}
  unrelatedProp = "a prop that's not a method"
}

我想要一个看起来像这样的类:

class MyHelper {
  mainClass: MainClass; 
  // ... this does a bunch of other stuff not related to `MainClass`
}

const main = new MainClass();
const helper = new MyHelper(main);

helper.myMethod(2) // ← I want to extend `myMethod` to accept, for example, `string | number`.

首先,我不确定这是否是一件事,并且有比使用代理更好的方法来做到这一点,但我正在这样做:

type ExtendFirstParamType<T extends (...args: any[]) => any, U>  = [
  Parameters<T>[0] | U,
  ...Parameters<T>
]
// ^^^ First problem here:
// 1. I'll be able to use this type to only extend the first parameter,
// it'd be nice to create a generic which would extend at any index
// 2. I'd need to splice/shift the parameter, instead here I'm spreading
// the rest of the parameters, so I'll get the first parameter again.

class MyHelper {
  constructor(public mainClass: MainClass) {
    const handler = {
      get(target: MainClass, propKey: keyof MainClass) {
        const property = target[propKey];

        if(typeof property !== "function") return property;
        else {
          return (...args: ExtendFirstParamType<typeof property, number>) => {
            // ^^^ Here you can see by hovering that the type is on the right track
            // it correctly infers that the first argument is now `string | number`
            return property.apply(this, args as any);
          }
        }
      }
    }

    this.mainClass = new Proxy(page, handler);
    // ^^^ How would I make sure that this type would be the proxied/extended
    // class? If I don't declare it in my class it complains that it doesn't exist
    // but if I declare it, and type it as `MainClass`, `myMethod` would not have
    // the new proxied type signature

  }
}

这是迄今为止我所拥有的Typescript 游乐场链接。

标签: typescriptproxy-pattern

解决方案


推荐阅读