首页 > 解决方案 > 如何在泛型函数中引用“typeof T”?

问题描述

function isSameOrSubclass<T>(target:any,reference:typeof T):target is T
{
    const   targetIsReference   = target===reference,
            targetIsTruthy      = target&&true,
            targetHasPrototype  = "prototype" in target,
            targetIsSubclass    = targetIsTruthy&&targetHasPrototype&&(target.prototype instanceof reference)
    return targetIsReference||targetIsSubclass;
}

编译器失败并出现以下错误:

TS2693:'T' 仅指一种类型,但在此处用作值。

替换typeof Tnew()=>T允许编译,但不允许这样做:

isSameOrSubclass<Class>(foo,Class)

因为

'typeof Class' 类型的参数不能分配给'new () => Class' 类型的参数。

标签: typescriptgenericstypescript-generics

解决方案


T需要限制为extends new() => {}*或类似的,然后直接使用(而不是 via typeof),如下所示:

function isSameOrSubclass<T extends new() => {}>(target:any,reference: T):target is T
// −−−−−−−−−−−−−−−−−−−−−−−−^^^^^^^^^^^^^^^^^^^^−−−−−−−−−−−−−−−−−−−−−−−−^
{
    const   targetIsReference   = target===reference,
            targetIsTruthy      = target&&true,
            targetHasPrototype  = "prototype" in target,
            targetIsSubclass    = targetIsTruthy&&targetHasPrototype&&(target.prototype instanceof reference)
    return targetIsReference||targetIsSubclass;
}

*或类似:该类型new() => {}指的是具有零参数构造函数的类。因此,要接受具有一个或多个参数的构造函数的类,需要不同的类型。IEnew(...args) => {}

然后你在没有任何显式类型参数的情况下使用它,如下所示:

class Parent {}
class Child extends Parent {}
class Unrelated {}
console.log(isSameOrSubclass(Child, Parent));      // true
console.log(isSameOrSubclass(Parent, Parent));     // true
console.log(isSameOrSubclass(Parent, Unrelated));  // false

游乐场链接


推荐阅读