【问题标题】:How can I check instanceof in this TypeScript code at runtime?如何在运行时检查此 TypeScript 代码中的 instanceof?
【发布时间】:2017-11-01 01:49:39
【问题描述】:

我正在尝试在运行时检查变量是否是 ZeroMQ 的 Socket 的实例。在 JavaScript 中,这是可行的:

doCheck(input) {
    if (input instanceof zmq.Socket) {
        console.log("Is a socket.");
    }
    else {
        console.log("Is not a socket.");
    }
}

但是在 TypeScript 中,它抱怨 zmq.Socket,说它没有从类型定义文件中导出。该文件将Socket 定义为接口,因此它不是检查它是否为实例的正确类型。如何让instanceof 支票生效?

【问题讨论】:

    标签: javascript typescript zeromq


    【解决方案1】:

    如果zmq.Socket 导出为接口,则您不能在此类型上使用instanceof。您可以在实现中乱来查看实际实例化了哪个类,但这会很混乱且不可靠。

    一种选择是检查对象上是否存在您期望的几种方法,并将其放入类型保护函数中,以便以后可以根据需要进行更改:

    import * as zmq from 'zmq'
    
    function isSocket( sock: any ) : sock is zmq.Socket {
        var castSock = sock as zmq.Socket;
        // If it has all the methods it's probably a zmq.Socket
        return castSock.getsocketopt !== undefined
            && castSock.connect      !== undefined
            && castSock.disconnect   !== undefined
            && castSock.close        !== undefined;
    }
    
    function doCheck(input) {
        if (isSocket(input) ) {
            input.close() // input is of a type zmq.Socket
            console.log( "Is a ZeroMQ Socket instance." );
        }
        else {
            console.log( "Is not a ZeroMQ Socket instance." );
        }
    }
    

    编辑:

    如果instanceof 代码在纯 JS 中有效,则意味着定义错误,Socket 实际上应该是一个类。您可以更正它并将其提交给项目,但同时您可以在您使用的文件中添加以下代码instanceof

    declare module 'zmq' {
        export class Socket {}
    }
    
    function doCheck(input : zmq.Socket | string) {
        if (input instanceof zmq.Socket) {
            input.close() // input is of type zmq.Socket
             console.log( "Is a ZeroMQ Socket instance." );
        }
        else {
            console.log( "Is not a ZeroMQ Socket instance." );
        }
    }
    

    【讨论】:

    • 那么你是说没有办法回到 JavaScript 提供的功能?
    • @Jez instanceof 会在纯 js 中工作吗?如果是,则定义错误,应予以纠正
    • 是的,它在纯 JS 中工作。我将如何修复定义?目前它是一个界面。
    • 好的,我会在一秒钟内解决问题
    【解决方案2】:

    你不能检查instanceof 接口,因为它是 Typescript 唯一知道的类型。编译后所有接口和类型都被删除,因此在执行的 javascript 代码中没有可以依赖的类型/接口。如果你想检查instanceof,你需要提供某种构造函数。

    您可以查看 Playground sn-p,它显示了它是如何工作的 here。注意编译后的代码没有接口。

    您可以查看官方文档以获取更多描述性解释here

    【讨论】:

      【解决方案3】:

      除了尝试一些类型推断分析、重铸等,
      我建议

      建立在相当明确的测试之上:

      让我们假设,在设计者决定支持的最低 API 版本是多少之后,已经有一些推理,然后,每个 ZeroMQ Socket 实例必须为每个实例提供无异常响应每个 API 记录的请求:

      try {
          var aLinger = inputUnderTest.getsockopt( zmq.LINGER     ); // ZMQ_LINGER
          var aCpuAfi = inputUnderTest.getsockopt( zmq.AFFINITY   ); // ZMQ_AFFINITY
          var aMaxMSZ = inputUnderTest.getsockopt( zmq.MAXMSGSIZE ); // ZMQ_MAXMSGSIZE
          var aRecvBF = inputUnderTest.getsockopt( zmq.RCVBUF     ); // ZMQ_RCVBUF
          var aRecvWM = inputUnderTest.getsockopt( zmq.RCVHWM     ); // ZMQ_RCVHWM
          var aRecvTO = inputUnderTest.getsockopt( zmq.RCVTIMEO   ); // ZMQ_RCVTIMEO
          var aRecvMO = inputUnderTest.getsockopt( zmq.RCVMORE    ); // ZMQ_RCVMORE
          var aSendBF = inputUnderTest.getsockopt( zmq.SNDBUF     ); // ZMQ_SNDBUF
          var aSendWM = inputUnderTest.getsockopt( zmq.SNDHWM     ); // ZMQ_SNDBUF
          var aSendTO = inputUnderTest.getsockopt( zmq.SNDTIMEO   ); // ZMQ_SNDTIMEO
          var aFDESCR = inputUnderTest.getsockopt( zmq.FD         ); // ZMQ_FD
      
          console.log( 'Seems to match a ZeroMQ Socket instance.' );
      
      }
      catch (e){
      
          console.log( 'Was not a ZeroMQ Socket instance.' );
      
          }
      }
      

      任何未能以无异常方式响应意味着:
      或者,inputUnderTest 不是 ZeroMQ Socket 实例 Q.E.D.

      ZeroMQ API 版本或特定语言的绑定/包装器实现已经悄悄地悄悄地在我们的脖子后面悄悄地改变了:o)

      其中任何一个都有助于决定我们接下来的步骤。

      【讨论】:

        猜你喜欢
        • 2012-09-16
        • 1970-01-01
        • 2016-07-15
        • 1970-01-01
        • 2016-07-24
        • 2020-08-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多