Given a generic class Foo<T>
with a static factory
method:
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.
This does compile however:
var f = Foo<number>().factory(1);
Why are the parenthesis required? Is this invoking the constructor?
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
.
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.instanceMethod(123); // OK
f.instanceMethod('123'); // Compile error
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)
// 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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With