-
Notifications
You must be signed in to change notification settings - Fork 3.2k
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
Provide strong types for 'invoke' command (#4022) #4950
Conversation
wow @mayfieldiv this is nice! Let us look at it, we had so much fun discussing the TS problem yesterday. I wonder about updating TS all the way to v3.4.0 |
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.
Thank you so much for your work! It's really cool
* Handles functions with up to 5 overloads | ||
*/ | ||
type OverloadedReturnType<T, TArgs extends unknown[]> = | ||
T extends { (...args: infer A1): infer R1; (...args: infer A2): infer R2; (...args: infer A3): infer R3; (...args: infer A4): infer R4; (...args: infer A5): infer R5; } ? |
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 think we can expose all this types to separate types like AnyFunction5Args
. I think it will not be a giant problem?
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.
We could split into many separate types like:
type Process5ArgFunction<T, TArgs> =
T extends { (...args: infer A1): infer R1; (...args: infer A2): infer R2; (...args: infer A3): infer R3; (...args: infer A4): infer R4; (...args: infer A5): infer R5; }
? ValidReturn<TArgs, A1, R1> | ValidReturn<TArgs, A2, R2> | ValidReturn<TArgs, A3, R3> | ValidReturn<TArgs, A4, R4> | ValidReturn<TArgs, A5, R5> : never
...
but I'm not sure how much that would accomplish. Is that what you mean? I think the main complication with commonization is that we need the individual inferred types.
Something of note is that the results with earlier TS versions don't seem too bad.. Although I haven't looked into it too much, it seems to fall back to less restrictive return types based on the test failures.
|
Sorry for the delay on this. I probably messed up the merge conflicts since we've updated the invoke command since this was open.
|
@mayfieldiv Will you be able to look at the merge conflicts + lint errors on this PR? If not, we will need to close due to inactivity. |
4dd4a4d
to
3d03337
Compare
8d4f121
to
77c96a4
Compare
I've rebased and resolved the merge conflicts and lint errors. Everything passes, but it looks like the new version of Edit: I've added types to the One caveat is that in order to get the index argument to narrow the types of the parameters/return of the selected function, the user has to explicitly inform typescript that the array is actually a tuple of functions, as you can see in the tests I added. It may be necessary to add another overload that falls back to less restrictive types in the case that |
Yes, there was some debate over its usecase within our team as well 😅, but it is keeping the same signature as |
@@ -4,7 +4,7 @@ | |||
// Mike Woudenberg <https://github.com/mikewoudenberg> | |||
// Robbert van Markus <https://github.com/rvanmarkus> | |||
// Nicholas Boll <https://github.com/nicholasboll> | |||
// TypeScript Version: 2.9 | |||
// TypeScript Version: 3.4 |
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.
this is a pretty big jump. Is this normal? Should we maintain 2 versions of type definitions: one v2 and another v3?
cy.wrap(obj).invoke('bar.baz', 2).should('equal', 3) // $ExpectError | ||
cy.wrap(obj).invoke('foo', 5, 1) // $ExpectError | ||
cy.wrap(obj).invoke('foo', 5, 'b', 1) // $ExpectError | ||
cy.get('input').then(it => it[0]).invoke('checkValidity') // $ExpectError |
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.
can you namepace the input element tests more, they get lost mixed like this with wrapped object tests. Also, this needs probable needs a few complementary tests like
// checkValidity is a valid method on jQuery object, right?
cy.get('input').invoke('checkValidity') // $ExpectType Chainable<boolean>
cy.get('input').its(0) // $ExpectType Chainable<HTMLInputElement>
// but not on the underlying DOM element
.invoke('checkValidity') // $ExpectError
@mayfieldiv Are you able to address the comments from bahmutov above related to this PR? We'll have to close the PR if you are unable to address due to inactivity. |
Unfortunately we have to close this PR due to inactivity. Please open a new PR addressing the original issue and any requested changes. |
Closes #4022 (1st attempt -> #4907)
Provides strong typing for arguments and return type of
invoke
command. Also ensuresfunctionName
is the key of a function on theSubject
.This PR is much crazier than the first in order to address the issue detailed in #4022 (comment), as well as other issues that came up, e.g. functions with no parameters.
I expanded the test cases to cover several more scenarios; not all of those tests pass under TypeScript 3.3, but work with 3.4+.
BTW, I totally understand if there's too much craziness in here to merge; I'm just glad this was a nice problem for playing with complex types.
Pre-merge Tasks