Skip to content
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

Inconsistent TS2345 error when using function generics #50818

Closed
moshest opened this issue Sep 17, 2022 · 18 comments Β· Fixed by #52728
Closed

Inconsistent TS2345 error when using function generics #50818

moshest opened this issue Sep 17, 2022 · 18 comments Β· Fixed by #52728
Assignees
Labels
Bug A bug in TypeScript Fix Available A PR has been opened for this issue
Milestone

Comments

@moshest
Copy link

moshest commented Sep 17, 2022

Bug Report

πŸ”Ž Search Terms

  • Inconsistent 2345
  • function generics
  • extends 2345
  • generics 2345

πŸ•— Version & Regression Information

  • This changed from version 4.7.4+ and above

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

function func<T extends { foo: 1 }>(arg: T): void {}

func({ foo: 1, bar: 1 });

πŸ™ Actual behavior

bar property sometimes displayed as valid and sometimes produce an error:

Argument of type '{ foo: 1; bar: number; }' is not assignable to parameter of type '{ foo: 1; }'.
  Object literal may only specify known properties, and 'bar' does not exist in type '{ foo: 1; }'.(2345)

When playing with the code live and change bar to bar222 or ba sometimes the error shown and sometimes not.
Refreshing the playground link with the changes always remove the error.

Screen.Recording.2022-09-17.at.20.20.57.mov

πŸ™‚ Expected behavior

Always display as valid without any error.

{ foo: 1, bar: 1 } is a valid subtype of { foo: 1 } and so can legally be used to instantiate T.


Maybe related to #49490

@fatcerberus
Copy link

Expected behavior: Always display an error for unknown properties.

The correct behavior is for there to be no error here: excess property checks aren’t intended to apply to generic constraints. { foo: 1, bar: 1 } is a valid subtype of { foo: 1 } and so can legally be used to instantiate T.

@moshest
Copy link
Author

moshest commented Sep 18, 2022

@fatcerberus you are right, I've updated the issue description.

@RyanCavanaugh RyanCavanaugh added the Bug A bug in TypeScript label Sep 19, 2022
@RyanCavanaugh
Copy link
Member

This looks similar to some other bugs we've seen reported where weird errors show up while typing

@JonathonChen
Copy link

JonathonChen commented Sep 23, 2022

I also encounter the similar situation when passing function paramter in different ways.(typescipt version 4.1.3)

interface AAA {
  hyYears: Array<any>;
}

function func(process: AAA) {
  console.log(process);
}

const unresolveParams = {
  hyYears: [],
  periodDataId: 1,
};


func(unresolveParams); // why this line can't detect the extra parameter

func({
  hyYears: [],
  periodDataId: 1, //  ts(2345) detect the extra parameter. Argument of type '{ hyYears: undefined[]; periodDataId: number; func(unresolveParams: any): any; }' is not assignable to parameter of type 'AAA'
});

@Andarist
Copy link
Contributor

Andarist commented Oct 13, 2022

If only I bisected this correctly, the regression has been introduced by #36747

@Andarist
Copy link
Contributor

@JonathonChen your case is not a bug, you can learn more about this here

@jakebailey
Copy link
Member

@Andarist How did you happen to reproduce this? Just using the editor or did you manage to get a test working? (I so far have not...)

@Andarist
Copy link
Contributor

I was using the editor with TS built from different commits. I was doing that within the TS repo itself so I could pretty easily jump between commits/builds

@jakebailey
Copy link
Member

Darn πŸ™

I haven't yet found the right fourslash calls to get this reproducing, so into the server RPC logs I go...

@jakebailey
Copy link
Member

jakebailey commented Oct 14, 2022

Got it:

////declare function func<T extends { foo: 1 }>(arg: T): void;
////
////func({ foo: 1, bar/*1*/: 1 });

goTo.marker("1");
edit.insert("2");
verify.completions({ exact: undefined });
verify.noErrors();

(I spent all that time figuring out how to assert in fourslash that there are no completions so I could perform the request.)

@OxleyS
Copy link

OxleyS commented Feb 10, 2023

You may interested in a similar issue I filed in the realm of "errors that only show up while typing": #51661

I don't know if it's the same underlying cause, or if my brief investigation into it was way off the mark or not, but food for thought.

@Andarist
Copy link
Contributor

@OxleyS unfortunately, this looks like a different problem, especially given the call stack shared here

@moshest
Copy link
Author

moshest commented Feb 17, 2023

Amazing! πŸ™Œ
I can confirm it resolved on nightly build using the playground link.

@maxmezzomo
Copy link

I ran into similar issue, initially with generics, but the simplified to even without generics. I am still not sure what was causing inconsistencies in different situations, but I did find that having a property with the name "name" seemed to cause the error reporting, I dont know if word is reserved or something, either way thought would share if its useful at all https://www.typescriptlang.org/play?#code/FAFwngDgpgBAsmA8gIwFZQMYhgXhgb2GBhgCcoBDAEwHsA7AGzBgDcKGBXKAZwC4DiJMpVqNmdCgFso-biFIBLOgHMA3IIC+6rUQz05MACIBBACrH+CFOiy4BJNpx79CQmBOn8ARI65eANJqBOrr62NxQIADCFNg4ggAUvjLwSGiYIADaPuxc3F4AugCUuAB8iRR0CpLsfKnWGUWWaTZxpTAJrkIAdL2V1bWBbsl1yUMwGkXqwHp0BgDuNKQA1tx2EdGxnR4yXnRQ8zAYsV6ToXPhABY0HAxUABIULFAAoqSkS+uRMSAJCSU4dr-ModAFA-DuKQpPYHGAANVyUC8EyKRQSJnMUyIQA

@jakebailey
Copy link
Member

I see no error in the above snippet, so if you're having a problem and can reproduce it without generics, I would suggest making a new issue as that's very likely different.

@maxmezzomo
Copy link

Great thank you, before I create an issue I would appreciate if you could take a glance at

https://www.typescriptlang.org/play?ssl=16&ssc=30&pln=15&pc=1#code/FAehGUAsEMAcFMAEB3AlgF0ogdtAtkgGarwA2AJsOgJ4KIDyARgFbwDG6A6hpAHL7wACgCcA9rEQBeRAG9cBAFwBndMNTYA5gF8A3MGBtR2FYlhrs6JsymIAFKJYKr7Lj34ER4gJSSAfIeNRUngAOlJRDXsWL30zdUsWWzkBBQAiADdoUgBXeFStGLiLK1tbH18k+Xg0yDJwxCVIUWzyREYkeGExYQB+fK8vRDBsUURO7v0wBoFEQ3IkUBBuTERoRHJUQkJO+AsGmAQqWiRnDmXIABFN7eFd9E8JaRlMnOqVc209AyMTIvQrrZWGxRZhOFguc4Am53B7lAJKIKhcKRBzMGLAP5QkrPLK5NIvXL9DHmf7XEplPxJAnVVJjLqiYT9QZTcYMoA

It's a little clearer than the above one but same thing. The fact there is no error is the issue as I understand, it should not accept function, but seems to when field is called 'name', just to make sure its not something already known. Thanks

@jakebailey
Copy link
Member

This PR issue in particular is about inconsistent errors in the editor while modifying code, so your sample is definitely not related.

But, yes, I'm pretty sure your code behaves that way because functions have a name property and so satisfy the first object type in your example. e.g.:

image

@maxmezzomo
Copy link

Nice, thanks for clarifying, feel free to hide or delete my posts if useful, cheers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Fix Available A PR has been opened for this issue
Projects
None yet
9 participants