【问题标题】:Typescript + ES6 Proxy打字稿 + ES6 代理
【发布时间】:2020-08-30 18:29:56
【问题描述】:

ES6 Proxy.apply 方法提供了一种使用没有“new”关键字的类的方法。

但在 TypeScript 上,它会给出错误“'typeof ClassName' 类型的值不可调用。您的意思是包含 'new' 吗?”。

有什么方法可以防止 TypeScript 错误?

这是一个简单的例子;

class ClassName {
  constructor(anyThing?: any) {
    if (anyThing) {
      // Do something
    }
  }
}

// ES6 Proxy
const CustomName = new Proxy(ClassName, {
  apply: (Target, _thisArg, argumentsList) => {
    return new Target(...argumentsList);
  }
});

// Test ---------
new ClassName("test"); // return ClassName { }

// No error
new CustomName("test"); // return ClassName { }

// Javascript: no error
// TypeScript: error => Value of type 'typeof ClassName' is not callable. Did you mean to include 'new'?
CustomName("test"); // return ClassName { }

【问题讨论】:

    标签: typescript


    【解决方案1】:

    使用 Target 的静态方法使 Proxy 可调用

    class ClassName {
      constructor(anyThing?: any) {
        if (anyThing) {
          // Do something
        }
      }
    
      // Forge
      static forge (anyThing?: any) {
        return new ClassName(anyThing);
      }
    }
    
    // ES6 Proxy
    const CustomName = new Proxy(ClassName, {
      apply: (Target, _thisArg, argumentsList) => {
        return new Target(...argumentsList);
      }
    }) as typeof ClassName & typeof ClassName.forge;
    
    let instance: ClassName;
    
    instance = new ClassName();
    instance = new CustomName();
    instance = CustomName();
    

    【讨论】:

    【解决方案2】:

    Typescript 无法理解您的 apply 函数对类的作用。您将需要扩充类型。

    解决方案 (playground)

    class ClassName {
      constructor(anyThing?: any) {
        if (anyThing) {
          // Do something
        }
      }
    }
    
    // ES6 Proxy
    const CustomName = new Proxy(ClassName, {
      apply: (Target, _thisArg, argumentsList) => {
        return new Target(...argumentsList);
      },
      get: () => { ... }, // Implement static method(s)
    }) as typeof ClassName & (() => ClassName) & { staticMethod(): CustomName };
    
    let instance: ClassName;
    
    instance = new ClassName();
    instance = new CustomName();
    instance = CustomName();
    instance = CustomName.staticMethod();
    

    【讨论】:

    • 谢谢,这是教 TypeScript 的一个好技巧,它是可调用的。可以引用函数还是静态方法?
    • 我添加了一个静态方法类型定义。要执行类方法,您需要类实例的另一个代理。
    • 我不是那个意思。我的意思是作为一个静态 create() 方法返回 new ClassName()。并将 CustomName 转换为 create() 方法。 - 如果一个静态方法不可用,至少一个函数。
    • 您能说明您希望如何使用该功能吗?我不明白。
    • 我添加了下一个答案。当然,不能引用构造方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-13
    • 2023-04-02
    • 2021-09-07
    • 2015-10-06
    • 2016-12-12
    • 2021-10-25
    • 1970-01-01
    相关资源
    最近更新 更多