如何在运行时检查此TypeScript代码中的instanceof?

时间:2017-10-31 12:27:45

标签: javascript typescript zeromq

我正在尝试在运行时检查变量是否是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检查工作?

3 个答案:

答案 0 :(得分:2)

如果将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." );
    }
}

答案 1 :(得分:1)

您无法检查instanceof界面,因为它只是Typescript已知的类型。编译后,所有接口和类型都被删除,因此在执行的javascript代码中,没有可依赖的类型/接口。如果要检查instanceof,则需要提供某种构造函数。

您可以查看显示其工作原理的游乐场代码段here。请注意,编译版本的代码中没有接口。

您可以查看官方文档,了解更详细的说明here

答案 2 :(得分:0)

除了尝试一些类型推理分析,重新铸造等,我建议建立在相当明确的测试上:

让我们假设,设计师已经做出了一些推理,决定支持的最低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)

其中任何一个都有助于决定我们的后续步骤。