如何为 is(constructor, instance) 方法编写打字稿定义

How to write typescript definition for is(constructor, instance) method

假设我有一个 is 函数,基本上这就是它的工作原理。

is(Array, []) // true
is(String, '') // true

因为它是一个 javascript 函数,我需要为它创建一个单独的打字稿定义。

现在我可以简单地实现下面的接口,

is(ctor: any, val: any): boolean;

但是这个定义不够好,因为在我 运行 if(is(Array, stuffA)) { ... } 之后 stuffA 的类型无法被 typescirpt 编译器推断 if 块中.

如何使 类型断言对 is 函数起作用

签名应如下所示:

function is<T>(type: { new(): T }, obj: any): obj is T

这将确保编译器理解正确的类型,即此函数被视为 a type guard

我也有这样的功能:

function is<T>(obj: any, type: { new(): T }): obj is T {
    if (Number.isNaN(type as any) && Number.isNaN(obj)) {
        return true;
    }

    let objType: string = typeof obj;
    let nameRegex: RegExp = /Arguments|Function|String|Number|Date|Array|Boolean|RegExp/;

    if (obj && objType === "object") {
        return obj instanceof type;
    }

    let typeName: RegExpMatchArray = type.toString().match(nameRegex);
    if (typeName) {
        return typeName[0].toLowerCase() === objType;
    }

    return false;
}

(code in playground)


编辑

使用这个函数时,我们总是传递一个实例,然后是 class。
因为我们希望函数涵盖所有类型,所以我们将使用泛型,其中 T 是传递实例的类型。

如果T是实例的类型,那么class的类型是:

{ new(): T }

这就是描述contrcutor对象的"typescript way"(也是class)。
可以在这里找到更多信息:Difference between the static and instance sides of classes.