Calling a static function for a generic class in TypeScript

Given the generic class Foo<T> with the static factory method:

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

Why is this not compiling?

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

Error message:

error TS2069: The parameter list should follow the list of arguments of a general type. '(' expected.

However, this compiles:

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

Why are parentheses required? Is this constructor called?

+7
typescript
source share
3 answers

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

For this reason, your static method must be generic and accept a type argument. I highlight this using U in a static function and T in a class. It is important to remember that the type of instance T does not match the type of static method U

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

Then you call it by passing the type argument immediately before the bracket, for example:

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

When type inference is possible, type annotation may be omitted:

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

The variable f is an instance of Foo with an argument of type number , so the instanceMethod method takes a value of type number (or any ).

 f.instanceMethod(123); // OK f.instanceMethod('123'); // Compile error 
+14
source share

The point here is that the static generic template is not associated with the class template (and therefore the instance). Therefore, we just need to distinguish between them (as in C #, I would 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 this way:

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

I think what happens is that the TypeScript compiler sees Foo<number> and expects it to be an object type ie

 var f: Foo<number>; 

Since the class is compiled using the scoped function in javascript, when you add a bracket, you actually initialize the yes object.

Typescript probably causes a compilation error without () because it cannot assume that you wanted to initialize the class.

0
source share

All Articles