【问题标题】:How to add type parameter's methods to a type that uses proxy如何将类型参数的方法添加到使用代理的类型
【发布时间】:2016-10-18 10:49:49
【问题描述】:

我正在开发一个简单的 RPC 客户端/服务器库供我内部使用。我想使用一个接口来描述客户端和服务器,这样我就可以在我的通用应用程序中的服务器和浏览器之间共享它们。

服务器很简单,服务只是扩展了我的 Service 类并实现了一个描述 API 的接口。

客户端将实现为 ES6 代理,只需将所有方法调用发送到服务器,我希望它具有强类型以及服务类。 我需要 ServiceClient 类型的实例来拥有它的类型参数的所有方法和属性,不管它是什么。

我在想这个语法:

interface Api
{
    foo(): boolean;
}

class MyService extends Service implements Api
{
    public foo(): boolean { return true; }
}

// usage
let result = (new ServiceClient<Api>()).foo(); // type of result is inferred, I get an error if I try to use an undefined method, arguments are type checked...

我尝试浏览一些类似的类型,但找不到方法。感谢您的帮助。

【问题讨论】:

  • 你到底在问什么?
  • 如何让 ServiceClient 从 T“继承”方法,而不需要实际继承和实现它们。
  • 您的代码似乎缺少某些部分,Service 是什么,ServiceClient 是什么?请分享所有需要的代码。
  • @NitzanTomer 我不知道要在 ServiceClient 中添加什么,除了我的代理实现(这是不相关的),这是我的问题。 Service 只是一个普通的父类型,目前它是空的,但将来它会持有一个构造函数,将它注册到 HTTP 服务器。
  • 基本上我需要以某种方式修改我调用“new”时创建的类型 - 编译时,它应该在运行时保持正常。

标签: typescript ecmascript-6 es6-proxy


【解决方案1】:

我希望我能理解你在问什么。

您不能在运行时使用泛型参数 (T),因此您不能动态创建实现 T 中所有方法的代理对象。

你可以这样做:

interface Api {
    foo(): boolean;
}

abstract class Service {}

class MyService extends Service implements Api {
    public foo(): boolean { return true; }
}

const myService = new MyService();
const ServiceClient = {} as Api;
for (let key in myService) {
    if (typeof myService[key] === "function" && key !== "constructor") {
        ServiceClient[key] = function() {
            return myService[key].apply(myService, arguments);
        }
    }
}

let result = ServiceClient.foo(); // true

(code in playground)

我所做的是创建了一个MyService 的实例,然后我创建了一个对象,它将作为这个myService 的代理,这个代理ServiceClient 最初是作为一个空对象创建的。
然后我遍历MyService 实例的属性,并为每个函数(不是构造函数)在代理对象上创建一个具有相同名称的函数,当每个函数被调用时,@ 中的等效函数987654329@被调用。


编辑

如果我理解了,那么您需要做的就是告诉编译器您的实例是Api 类型:

class ServiceClient {
    // implement proxy magic here
}

let client = new ServiceClient() as any as Api;
let result = client.foo();

这应该可以解决问题,因为它会创建代理事物的类的实例,然后诱使编译器认为这是Api 的实例。

【讨论】:

  • 但是ServiceClient类不应该绑定到Api接口。我在运行时不需要任何支持,我唯一的一点是要有强类型。 ServiceClient 类将包含一个 ES6 代理,它将观察任何方法调用,并通过套接字将它们代理到服务器。我需要一种方法来制作具有我指定为其类型参数的任何接口的方法和属性的 ServiceClient 实例。
  • 我创建的代码将用作外部库,用户将只提供描述 API 和服务类的接口,处理服务器端,仅此而已。跨度>
  • 我需要“new ServiceClient()”来创建“ServiceClient & T”的交集类型,因此我可以使用 T 中的方法,并且编译器在其返回类型和论据。
  • 这在打字稿中是不可能的。你只能有接口。但是如果你想要一个类(你可以实例化),那么你需要预先知道所有的方法。
  • 我已经创建了一个函数:“function createClient(): JsonRpcServiceClient & T { return (new JsonRpcServiceClient()) as JsonRpcServiceClient & T; }”满足我的需要。当然没有办法使用“new”关键字来执行此操作,因为这会在我的应用程序中添加不必要的执行层?
猜你喜欢
  • 2016-08-20
  • 1970-01-01
  • 2012-06-02
  • 1970-01-01
  • 1970-01-01
  • 2016-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多