I have a factory-like function that is meant to return an sub-class instance of BaseApi
. It currently looks something like this (trimmed out irrelevant parts):
function getApi<T extends BaseApi>(apiClass: typeof BaseApi): T { return new apiClass(); }
And I use it like this:
const someApi = getApi<SomeApi>(SomeApi);
This works, but I would like <SomeApi>
to be inferred by virtue of the fact that I'm passing the SomeApi
constructor in. If I omit <SomeApi>
then someApi
is inferred to be of type BaseApi
, not SomeApi
. Worse, there's really no compiler correlation between <T extends BaseApi>
and typeof BaseApi
being the same thing, so you can incorrectly do something like getApi<SecondApi>(FirstApi)
without a compiler error.
So I tried defining the apiClass
as typeof T
:
function getApi<T extends BaseApi>(apiClass: typeof T): T { return new apiClass(); }
And I found that TS did not understand this usage of T
. Is there any way to do this?
Use the IsGenericType property to determine whether the type is generic, and use the IsGenericTypeDefinition property to determine whether the type is a generic type definition. Get an array that contains the generic type arguments, using the GetGenericArguments method.
T is called type parameter, which can be used as a type of fields, properties, method parameters, return types, and delegates in the DataStore class. For example, Data is generic property because we have used a type parameter T as its type instead of the specific data type. Note.
Assigning Generic ParametersBy passing in the type with the <number> code, you are explicitly letting TypeScript know that you want the generic type parameter T of the identity function to be of type number . This will enforce the number type as the argument and the return value.
The actual type arguments of a generic type are. reference types, wildcards, or. parameterized types (i.e. instantiations of other generic types).
What you actually want is new() => T
, since you intend to use the argument as a constructor and produce a T
. Even if you could write typeof T
, that wouldn't be what you want, since T
might not have a zero-argument constructor.
Remember that the typeof
operator takes a value and produces a value. T
is already a type; it is not a value.
Naturally, this is addressed in the TypeScript FAQ https://github.com/Microsoft/TypeScript/wiki/FAQ#why-cant-i-write-typeof-t-new-t-or-instanceof-t-in-my-generic-function
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