-
Notifications
You must be signed in to change notification settings - Fork 3k
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
fix(reduce): fix overload ordering #2382
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me, but would you mind add some test cases failing before and fixed by this PR?
@kwonoj Thank you, I most definitely will. |
Actually no it is just that the assumptions about where the type argument inference for |
Generated by 🚫 dangerJS |
@aluanhaddad it looks like there are build errors with the specs. Do you think you can fix them? |
Yes I've been very busy recently. I will try to fix them tonight and add some additional tests as well. When I looked at the specs, they seemed to rely on the seed being inferred to have the value type of the Observable. I need to double-check if that is the case. |
…iling specs This adds tests for both existing behavior, under the old overload, and the new behavior enabled by the new overload signatures of the `reduce` operator. Not that the specific change to the following test case `'should accept T typed reducers'` that removes the seed value. If a seed value is specified, then the reduction is always from `T` to `R`. This was necessary to make the test pass, but also models the expected behavior more correctly. The cases for `R` where `R` is not assignable to `T` are covered by new tests added in the commit. Additionally, I have added additional verification to all of the tests touched by this change to ensure that the values returned are usable as their respective expected types.
I am having some trouble replicating the test failures locally. npm run build_spec && npm run test_mocha && node ./node_modules/markdown-doctest/bin/cmd.js Any tips would be greatly appreciated. Nevermind, I got it working. |
Fix ordering as allowed by newly required seeds to fix failing tests. I think there is a good argument to be made that the failing tests were failing correctly, as this is how `Array.prototype.reduce` behaves, but as I have made the seed arguments required, for `R` typed reducers, re-ordering the overloads impacts their specificity allowing, the current behavior, correct or otherwise, to be retained.
@kwonoj I added several new test including tests covering behavior that was an error before these changes. I added a local binding and a subsequent statement to each test I touched so that the resulting value is now used in such a way that it validates that the types are propagated. Let me know if these tests are sufficient and also let me know if I should have added the same tests to |
I think this change is ready, re-approving. /cc @david-driscoll for second eye just in case. |
type(() => { | ||
let a: Rx.Observable<{ a: number; b: string }>; | ||
a.reduce<{ a?: number; b?: string }>((acc, value) => { | ||
const reduced = a.reduce<{ a?: number; b?: string }>((acc, value) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is a separate test required for generic type argument inference of R
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe so. Failure to infer R
as distinct from T
and T[]
was the original issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@aluanhaddad This test doesn't seem to be verifying correct inference, because it specifies the generic type arg explicitly. Probably for an inference test you'd repeat this without the explicit type argument, then try to assign reduced
to a variable of the explicit type you expect to have been inferred.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My bad, just realized the "R is not assignable to T" test already covers inference. 👍
lgtm |
@david-driscoll can you review this please? <3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no idea how I missed this after being pinged several times... 👍
Just to note, when I first looked at this, I believed the issue was simply due to the overload ordering but the root cause turned out to have as much to do with the optionality of the seed arguments as signature ordering. The now required seed arguments eliminate a previously applicable overload from the candidate set, but a minor order change was still ultimately necessary. |
Thanks @aluanhaddad !!! |
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Description:
Type inference for
Observable.prototype.reduce
currently behaves incorrectly, resulting in spurious type errors, in many common cases, when the type ofseed
is a different type than the value type of the Observable.One of the declared overloads is intended to specifically cater to this scenario but fails to do so because of its ordering with respect to the other overload declared.
The overload in question takes two type arguments,
T
andR
, making it more specific than the overloads declared before it.Due to TypeScript's overload resolution algorithm, which picks the first matching overload, this overload does not have the intended effect.
This is documented here https://www.typescriptlang.org/docs/handbook/declaration-files/do-s-and-don-ts.html in the section entitled Function Overloads, under the Ordering heading, which states
Related issue (if exists):
This fixes #2338