-
Notifications
You must be signed in to change notification settings - Fork 12.8k
3.5.1 strictFunctionTypes broke code. #31698
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
This issue is very hard to debug without providing the definition of It's likely that the first type parameter of |
@jack-williams Updated example and code repo above. |
The new error looks correct to me. declare let a: MyType<[any]>;
declare let b: MyType<any[]>;
a(); // error, need at least one argument.
b(); // ok, we can have 0 or more arguments.
b = a; // aliasing away `a` should not let us violate the arity of `a` The function |
So I take it as the contravariant check for the above example is not working as expected in 3.4.5? |
So actually I'm abit confused now...sorry! The error looks correct to me: assigning declare let c: (x: any) => any;
declare let d: (...x: any[]) => any;
c(); // error, need at least one argument.
d(); // ok, we can have 0 or more arguments.
d = c; // no error! This is clearly inconsistent. I'm guessing there is some logic in call signature checking that allows this, but this logic is never reached due to alias/interface variance flags. You can tell this from the following example: type MyType<T extends any[]> = (...args: T) => any;
type MyType2<T extends any[]> = (...args: T) => any;
declare let a: MyType<[any]>;
declare let b: MyType2<any[]>;
b = a; // no error now because `a` and `b` are different aliases I think this will need input from someone one the team. IMO assigning |
Variable args in a source signature are assumed to all be present (if requested) in the target signature. A reasonably common pattern is a function that takes a callback and invokes it with a deterministic but finite number of arguments, e.g. function makeCall(arr: any[], func: (...args: any[]) => void) {
func.apply(null, arr);
}
makeCall([1, 2, 3], (x, y, z) => undefined); We tried enforcing this back in 0.9 (0.8 had a bug that unintentionally allowed it) but people complained a lot and we ended up reverting it. |
The more you know! I guess the fix for this would be to add some more unmeasurable variance positions? (Or just revert the thing that changed it) |
Another difference in behaviours between type Options = { is: (value: any) => boolean } | object;
// Ok in 3.4.5 but got following error in 3.5.1:
// Types of property 'is' are incompatible.
// Type '(val1: any, val2: any) => boolean' is not assignable to type '(value: any) => boolean'.
let opt: Options = {
is: (val1, val2) => true
}; This behaviour in 3.5.1 seemed more correct, but |
This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
Uh oh!
There was an error while loading. Please reload this page.
TypeScript Version: 3.6.0-dev.20190531
Search Terms: strictFunctionTypes
Code
Repo: https://github.com/deskoh/sinon-ts-issue
Updated code:
Original example:
Expected behavior:
As described above.
Actual behavior:
As described above.
Playground Link: N.A. (TS 3.5.1 not available yet, see code repo above)
Related Issues: N.A.
The text was updated successfully, but these errors were encountered: