-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Incompatible code unexpectedly compiles due to intersection with empty mapped type #19869
Comments
Also interesting is if you change declare function takesNum(args: number): void
f1(["a"], [], takesNum) // now errors of course but with the totally incorrect inferred type of Args:
// Error:(20, 15) TS2345: Argument of type '(args: number) => void' is not assignable to parameter of type
// '(args: Args<"a", "toString" | "toFixed" | "toExponential" | "toPrecision" | "valueOf" | "toLocaleString">) => void'. |
FYI was looking through changes recently to guess what caused the behavior change and it seems almost certain to be #19745 so maybe this behavior is expected? Looking at the original bug(#19576) that was addressing I can see it'd be a very fine needle to thread to somehow both fail in my example and compile in the #19576 example. I did discover that I can work around half of my problem by doing: type Args<S extends string, N extends string> = Record<S, string> & Record<N, number>
declare function f2<S extends string, N extends string, F extends (args: Args<S, N>) => void>
(strs: S[], nums: N[], fun: F): void
declare function takesNum(args: {a: number}): void
declare function takesOptionalNum(args: {a?: number}): void
f2(["a"], [], takesNum) // Now correctly errors because of incompatibility of "a"
f2(["a"], [], takesOptionalNum) // *** Still unexpectedly compiles despite incompatibility of "a" ***
f2(["a"], ["b"], takesOptionalNum) // Now correctly errors because of incompatibility of "a" But as the comments show, the optional case still works incorrectly even after that. |
Should be addressed by #19912 |
I think this is working as intended and it isn't affected by #19912. In this call f1(["a"], [], takesNum); we make the inference f1(strs: "a"[], nums: "a"[], fun: (args: Args<"a", "a">) => void): void; which is equivalent to f1(strs: "a"[], nums: "a"[], fun: (args: { a: string } & { a: number }) => void): void; which is a signature for which all of the arguments are compatible. |
TypeScript Version: Version 2.7.0-dev.20171109
Code
Expected behavior:
All calls to
f1
should error becausetakesNum
andtakesOptionalNum
expecta
to be a number but it will actually be a string.Actual behavior:
It only errors if the second argument to f1 is not empty.
Also the first case shown above:
f1(["a"], [], takesNum)
actually errored as expected as recently as last week(I believe I was on 2.7.0-dev.20171031), it was only the optional case that unexpectedly compiled. I was about to open this for just the optional case when I checked the latest typescript version and noticed the first case started being affected also.The text was updated successfully, but these errors were encountered: