【问题标题】:Calling a static function on a generic class in TypeScript在 TypeScript 中调用泛型类的静态函数
【发布时间】:2014-06-18 16:58:40
【问题描述】:

给定一个带有静态factory 方法的泛型类Foo<T>

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

为什么不编译?

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

错误信息:

错误 TS2069:参数列表必须遵循泛型类型参数列表。 '(' 预期。

这确实可以编译:

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

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

【问题讨论】:

  • 不提在顶部代码块中出现编译错误这一事实似乎很奇怪(在静态方法中使用包含类中的类型参数是非法的)
  • @RyanCavanaugh,实际上我正在进行大型重构,WebStorm 报告了错误消息。他们对 TypeScript 的支持还可以,但不是那么全面。一定是错过了你所说的错误,或者我给出的错误掩盖了你描述的错误。

标签: typescript


【解决方案1】:

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

因此,您的静态方法必须是通用的并接受类型参数。我通过在静态函数中使用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

【讨论】:

    【解决方案2】:

    这里的重点是,静态通用模板与类 (因此实例) 模板无关。所以我们只需要区分它们(就像我在 C# 中所说的那样)

    // 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);
    

    【讨论】:

      【解决方案3】:

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

      var f: Foo<number>;
      

      由于该类在 javascript 中被编译为作用域函数,因此在添加括号时,您实际上是在初始化对象。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-09-19
        • 2023-01-12
        • 1970-01-01
        • 2018-07-03
        • 2015-04-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多