-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Mapped type function argument messes up return type #12633
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I guess |
I can partly work around the issue using a second type argument but I'm still blocked from creating a properly typed version of const assign = <T, P extends T>(target: T, ...sources: Array<Partial<P>>): T =>
Object.assign(target, ...sources);
let o = {a: 5, b: 7};
assign(o, {a: 9}); // ok
assign(o, {a: 9}, {b: 8}); // error: The type argument for type parameter 'P'
// cannot be inferred from the usage. Consider
// specifying the type arguments explicitly. Breaking it into separate functions works however: const assign = <T>(target: T) => (...sources: Array<Partial<T>>): T =>
Object.assign(target, ...sources);
let o = {a: 5, b: 7};
assign(o)({a: 9}); // ok
assign(o)({a: 9}, {b: 8}); // ok |
This version does seem to mostly work however: const assign = <T, P>(target: T, ...sources: Array<Partial<T&P>>): T =>
Object.assign(target, ...sources);
let o = {a: 5, b: 7};
o = assign(o, {a: 6}); // ok
assign(o, {a: 9}, {b: 8}, {}); // ok
assign(o, {a: 9}, {b: false}); // error
assign(o, {a: 9}, {b: 8}, {x: true}); // error
assign(o, {a: 9}, {b: 8}, 'no'); // ok - why? produces {0: "n", 1: "o", a: 9, b: 8} Edit: This issue of accepting strings (and other primitives) is tracked in #7485. |
Ideally we'd have a way of indicating that a particular parameter position should not be an inference location (a request that has come up before). That is effectively what happens when you say Alternatively, we could say that inferences made to mapped types are classified as secondary and would take effect only if no primary inferences are made. We already have the infrastructure in place to do this kind of classification. The downside would be that in cases where we make inferences to say a @mhegazy @DanielRosenwasser Opinons? |
I'm thinking that classifying inferences to mapped types as secondary is the right thing to do. My reasoning is that such inferences are (a) more speculative than direct inferences and (b) "lossy" because they drop private and protected properties and call and construct signatures. I will put up a PR. |
@ahejlsberg I think making mapped type inferences inferior to those of flat types (like in the PR) is probably the better move. We can see how much of an issue this is if it comes up often and circle back. |
TypeScript Version: nightly (2.2.0-dev.20161203)
Code
Expected behavior:
The return type of the function should be
{a: number, b: number}
, not{b: number}
Actual behavior:
The presence of a
Partial<T>
argument causes an incorrect return type. ReplacingPartial<T>
with{}
works around the bug.The text was updated successfully, but these errors were encountered: