Named Type Arguments & Partial Type Argument Inference - #23696
Named Type Arguments & Partial Type Argument Inference#23696Wesley Wigham (weswigham) wants to merge 14 commits into
Conversation
|
First question
I assume what you mean here is that something like the following isn't allowed: type Example<T, U> = { t: T, u: U }
type NotAllowed = Example<U = string> // not allowed because nowhere to infer T fromWould that be allowed though if the missing type arguments already have defaults specified? Example: type ExampleDefaults<T = any, U = any> = { t: T, u: U }
type IsThisAllowed = ExampleDefaults<U = string> // allowed?Second question
Does that mean the skipped type arguments will still be inferred even if they have a default? Example: declare function test<A = any, B = any>(arg: { a?: A, b?: B }): {a: A, b: B}
const r1 = test<string>({ b: "foo" })
const r2 = test<A = string>({ b: "foo" })What are the types of |
Yes, that should be fine. Though you've reminded me of a class of error I probably need to add a test and error for: type Two<A, B = number> = [A, B]
type Bug = Two<B = string> // should error, A was not provided
Yes, and if inference fails (ie, there are no inference sites) it still falls back to the default (which is always the case when inferring normal type parameters). As for your example, in the first call your result is |
With this PR, we allow named type arguments, of the form
Identifier = Typeanywhere a type argument is expected. This looks like so:These arguments do not need to come in any particular order, but must come after all positional type arguments. When you've used a named type argument, you may elide any other type arguments you wish. When you do so, the missing arguments will be inferred (and will not cause an error to be issued even if they do not have a default)
(This is not valid for typespace references such as type references - those still have strict arity checks as there is no inference source)
Fixes #22631
Fixes #20122
Fixes #10571
🚲 🏠: Should named type argument assignments use a
=(as they do in this PR now), or a:(as #22631 proposed)?