在 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
Calling a static function on a generic class in TypeScript
提问by Drew Noakes
Given a generic class Foo<T>
with a static factory
method:
给定一个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 U
in the static function, and T
in the class. It is important to remember that the instance type of T
is 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 f
is an instance of Foo
with a type argument of number
, so the instanceMethod
method will only accept a value of type number
(or any
).
该变量f
是Foo
一个类型参数为 的实例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 可能会在没有 的情况下引发编译错误,()
因为它不能假设您打算初始化该类。