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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24291216/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 02:54:44  来源:igfitidea点击:

Calling a static function on a generic class in TypeScript

typescript

提问by Drew Noakes

Given a generic class Foo<T>with a static factorymethod:

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

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

Why does this not compile?

为什么这不能编译?

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

The error message:

错误信息:

error TS2069: A parameter list must follow a generic type argument list. '(' expected.

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

This does compile however:

但是,这确实可以编译:

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

Why are the parenthesis required? Is this invoking the constructor?

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

回答by Fenton

Just as static methods cannot access instance members, the static method cannot use the instance type argument.

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

For this reason, your static method must be generic and accept a type argument. I highlight this by using Uin the static function, and Tin the class. It is important to remember that the instance type of Tis not the same as the static method type of U.

因此,您的静态方法必须是泛型的并接受类型参数。我通过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;
    }
}

You then call it by passing the type argument just before the parenthesis, like this:

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

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

When type inference is possible, the type annotation may be dropped:

当类型推断是可能的时,类型注释可能会被删除:

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

The variable fis an instance of Foowith a type argument of number, so the instanceMethodmethod will only accept a value of type number(or any).

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

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

回答by Radim K?hler

The point here is, that static generic template is not related to class (and therefore instance)template. So we just have to distinguish them (as in C# I'd say)

这里的重点是,静态泛型模板与类(以及实例)模板无关。所以我们只需要区分它们(就像在 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;
    }
}

and we can call it like:

我们可以这样称呼它:

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

回答by Pricey

I think what is happening is that the TypeScript compiler is seeing Foo<number>and is expecting this to be an object type i.e.

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

var f: Foo<number>;

Since the class is compiled to a scoped function in javascript, when adding the parenthesis you are effectively initialising the object yes.

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

Typescript probably raises a compile error without the ()because it can't assume that you meant to initialise the class.

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