Instantiation expressions#47607
Conversation
|
@ahejlsberg This is super close to a solution of #37181. Will it will allow us to do: Up to now |
|
Building the TypeScript playground for this PR would be better. |
Yes, you can indeed use that pattern to capture a generic return type of a generic function. This is something that previously wasn't possible. I'll update the PR description to include an example. |
|
Let's say we have a function f have a call signature What will this PR behave? They have different argument counts and even different different type constraints |
This works just fine: But an error occurs here: |
|
@typescript-bot test this |
|
Heya @ahejlsberg, I'm starting to run the inline community code test suite on this PR at 8e466ba. Hold tight - I'll update this comment with the log link once the build has been queued. |
|
It doesn't works on build-ins method 🤔 |
|
You cant use brackets, just qualified names: |
|
How to use this feature with overloaded functions ? I couldn't get the code to work. The error message is The code works if I change the second |
|
Higher-order instantiation expressions don't resolve properly, as they weren't accounted for in the test baselines (see also issue #52035). |
Is there any issue tracking a design for a way we could do that? I've been trying to do something that I'd be able to accomplish if I could have a type like Someone correct me if I'm wrong but it seems there's no way to do this for an arbitrary function. |
|
It also solves #20719. |
I don't believe there is. Instantiation expressions only work for values; you can't use a similar method in types. The following (direct instead of the type parameter) works: |


With this PR we implement Instantiation Expressions which provide the ability to specify type arguments for generic functions or generic constructors without actually calling them. For example:
Above, the instantiation expression
makeBox<string>changes the type ofmakeBoxfrom<T>(value: T) => { value: T }to the more specific type(value: string) => { value: string }. When emitted to JavaScript, instantiation expressions simply have the type arguments erased.Instantiation expressions are particularly useful for creating specific instantiations of generic class constructors such as the
ErrorMapabove. Previously, this could only be accomplished with a type annotation or a redundant subclass:The argument to the
typeoftype operator can now be an instantiation expression. For example:A particularly useful pattern is to create generic type aliases for applications of
typeofthat reference type parameters in type instantiation expressions:Notice how
Box<T>captures the inferred return type of a generic function without loosing the generic type. This was previously not possible.The type of an instantiation expression
f<T>is determined as follows:fis an object type,f<T>produces an object type in wherein generic signatures for which<T>is an applicable type argument list are instantiated with the given type arguments. Non-applicable signatures, including non-generic signatures, are elided, but other object type members (such as properties) are unaffected. An error occurs iffhas signatures, but none for which<T>is an applicable type argument list.fis a union or intersection type,f<T>produces a union or intersection type where the type argument list<T>has been applied to each constituent.fis a generic type,f<T>applies the type argument list<T>to the constraint of the type off.fis of any other type,f<T>has the same type asf.Note that an instantiation expression can be applied to any type, but that an error occurs if no call or construct signatures are present in the type. For example, an instantiation expression can be applied to a union that includes
undefined:Fixes #37181.
Fixes #40542.