在TypeScript中调用泛型类的静态函数

时间:2014-06-18 16:58:41

标签: typescript

给定具有静态Foo<T>方法的通用类factory

class Foo<T>
{
    public static factory(item: T): Foo<T>
    {
        return null;
    }
}

为什么不编译?

var f = Foo<number>.factory(1);

错误消息:

  

错误TS2069:参数列表必须遵循泛型类型参数列表。 &#39;(&#39;预期。

但这确实可以编译:

var f = Foo<number>().factory(1);

为什么需要括号?这是调用构造函数吗?

3 个答案:

答案 0 :(得分:18)

正如静态方法无法访问实例成员一样,静态方法也不能使用实例类型参数。

因此,您的静态方法必须是通用的并接受类型参数。我通过在静态函数中使用U和在类中使用T来强调这一点。请务必记住,T的实例类型与U的静态方法类型不同。

class Foo<T>
{
    public static factory<U>(item: U): Foo<U>
    {
        return new Foo<U>();
    }

    instanceMethod(input: T) : T
    {
        return input;
    }
}

然后通过在括号之前传递类型参数来调用它,如下所示:

var f: Foo<number> = Foo.factory<number>(1);

当可以进行类型推断时,可以删除类型注释:

var f: Foo<number> = Foo.factory(1);

变量fFoo的实例,其类型参数为number,因此instanceMethod方法只接受number类型的值(或any)。

f.instanceMethod(123);   // OK
f.instanceMethod('123'); // Compile error

答案 1 :(得分:1)

这里的要点是,静态通用模板与类(因此实例)模板无关。因此,我们必须区分它们(如在C#I中所说的那样)

// generic here is T
class Foo<T>
{
    public TheT: T;
    constructor(t: T)
    {
        this.TheT = t;
    }

    // the static one is U
    public static factory<U>(item: U): Foo<U>
    {
        var result = new Foo<U>(item);
        // the U here will be T inside of the instance
        return result;
    }
}

我们可以这样称呼:

var f = Foo.factory(<Number> 1);

答案 2 :(得分:0)

我认为正在发生的事情是TypeScript编译器正在看Foo<number>,并期望这是一个对象类型,即

var f: Foo<number>;

由于在javascript中将类编译为范围函数,因此在添加括号时,您实际上是在初始化对象是。

Typescript可能会在没有()的情况下引发编译错误,因为它不能假设您打算初始化该类。