-
Notifications
You must be signed in to change notification settings - Fork 29.9k
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
sinon: make calledWith partial #34048
Conversation
@43081j Thank you for submitting this PR! 🔔 @MrBigDog2U @rationull @lumaxis @nicojs @JoshuaKGoldberg @gjednaszewski @johnjesse @alecf @SimonSchick @bergundy - please review this PR in the next few days. Be sure to explicitly select If no reviewer appears after a week, a DefinitelyTyped maintainer will review the PR instead. |
@43081j The Travis CI build failed! Please review the logs for more information. Once you've pushed the fixes, the build will automatically re-run. Thanks! |
fyi build fails because the recent change to add nested matchers results in an inferred assertion type of looking into it |
@felixfbecker do you mind explaining your inspectable interface that was added not so long ago? did you introduce it so you could pass an array of spies? or was it for some other reason? basically it is causing trouble because TS3.1 can't infer the types correctly whereas 3.2 can. surely, if it was to solve the "array of spies" problem, |
A definition owner has approved this PR ⭐️. A maintainer will merge this PR shortly. If it shouldn't be merged yet, please leave a comment saying so and we'll wait. Thank you for your contribution to DefinitelyTyped! |
@43081j The Travis CI build failed! Please review the logs for more information. Once you've pushed the fixes, the build will automatically re-run. Thanks! |
alright here's a proposed solution (latest commit).
In strongly typed languages you'd usually do something like this (which isn't possible in TS): interface Foo {
prop1: string;
prop2: any;
}
interface Foo<T> extends Foo {
prop2: T;
} to get around the fact we can't quite do this, i named it instead This will be a breaking change in that the it is a bit incorrect though, as it now means the non-generic spies don't inherit let me know what you think DT maintainers DO NOT MERGE YET as i need feedback on this change (@SimonSchick and @felixfbecker if possible) |
The I don't really understand why |
Except you can't. A This is exactly why in most strongly typed languages, you have a non-generic base with generic sub classes. The same reason the array has problems, too. My change to make They fail because the recursive match arguments type results in While 3.3 and above seem to infer this correctly, it is still wrong. Better to rely less on an edge case of inference and instead just write the types a bit better. Additionally, the I still don't fully understand your train of thought. |
In your PR that introduced the inspectable stuff, things seemed fine until you wanted an array of spies. You then introduced the inspectable stuff. So I suspect the only reason you really needed any of this was so you can have a mixed array of generics, in which case it was the wrong way to do it and im surprised it worked at all (i guess the I'm just a little confused as to what it was for. Would you mind giving an example? |
@43081j The Travis CI build failed! Please review the logs for more information. Once you've pushed the fixes, the build will automatically re-run. Thanks! |
@43081j I haven't seen anything from you in a while and this PR currently has problems that prevent it from being merged. The PR will be closed tomorrow if there aren't new commits to fix the issues. |
@sandersn @sheetalkamat can one of you take a look at this? its becoming pretty aged but the problem still needs resolving and a cleanup of the now-cluttered interfaces would be nice. i've bumped into this problem (in the build) a lot, too, so whatever happens with this PR it would still be of great use to understand the general solution to it (single-use type params for handling tuples). if it turns out it needs changes in dtslint, ill do it. but it seems like there should be a solution without changing that. |
@43081j The Travis CI build failed! Please review the logs for more information. Once you've pushed the fixes, the build will automatically re-run. Thanks! |
@43081j simple suggestion before I finish reading the entire history: disable the lint rule that forbids single-use type parameters. tslint lets you disable rules for a single line. |
@sandersn if you don't mind that i will. i just thought it would be a bit hacky as i wasn't sure if the rule is in fact right and im doing something wrong. ill update if i have to disable the rule, does that mean the rule has a bug for this edge case? im happy to fix it if there is one i've also added a summary for you in the original post at the top |
bfcfd9f
to
615acaa
Compare
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.
The overall problem that SinonInspectable
attempted to solve was one of variance. By having both a call signature of TArgs
as well as various methods that both accept and return something with TArgs
, the type for TArgs
would become invariant in SinonSpy
. When we measure TArgs
as invariant, a SinonSpy
would only become assignable to another SynonSpy
where TArgs
is assignable in both directions. Unfortunately any[]
(the default for TArgs
) is not assignable to any tuple.
However, any
(rather than any[]
) is assignable in both directions, therefore SinonInspectable
isn't precisely necessary, but rather any instance of SinonSpy
where we don't care about the actual type of TArgs
we can replace with any
(rather than any[]
), and assignability should work correctly.
@rbuckton this is excellent, much appreciated taking the time to look through. i've made changes you suggested makes a lot more sense now that we should be using this has sat around for a long time and is why many people still haven't updated their types so it will be great to finally get it agreed on |
Thanks @rbuckton that is 100% accurate, I was unable to get the reason for |
It was already put across and well understood but was an unnecessary interface which didn't exist in sinon its self and was mostly to work around the array of generics in the end. there were various reasons the original attempt of using master currently has a rather bad breaking change preventing an update because of this workaround interface so if we're all happy with the new implementation that is great. would be good to get it merged |
🔔 @felixfbecker @rbuckton - Thanks for your review of this PR! Can you please look at the new code and update your review status if appropriate? |
I just published |
* sinon: make calledWith partial * sinon: only recursively allow matchers for objects * sinon: clean up non-generic bases * Revert "Extract inspectable spy API into own interface" This reverts commit e63af8d. * remove default args * remove default targs * use any for this only * reintroduce args param * use any for single use targs
npm test
.)npm run lint package-name
(ortsc
if notslint.json
is present).Fixes #33839
Summary of the mass of posts below & the changes here:
SinonInspectable
isn't a real thing, sinon has no such interface/concept, it has been removed from the typesSinonSpy
when used in spread has been changed to useany
asTArgs
(rather thanany[]
, the default) to allow having a collection of spies (trade-off we must make to avoid introducing a workaround interface like the wholeSinonInspectable
thing did)calledWith
is partial, so can accept some of the arguments rather than requiring them all