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

Type parameter inference regression in 3.4 #30442

Closed
ark120202 opened this issue Mar 16, 2019 · 3 comments · Fixed by #30857
Closed

Type parameter inference regression in 3.4 #30442

ark120202 opened this issue Mar 16, 2019 · 3 comments · Fixed by #30857
Assignees
Labels
Bug A bug in TypeScript Fixed A PR has been merged for this issue

Comments

@ark120202
Copy link

ark120202 commented Mar 16, 2019

TypeScript Version: 3.4.0-rc

Search Terms: Type parameters, generics, inference, regression

Code

const foo = <T>() => {};
const assign = <T, U>(a: T, b: U) => Object.assign(a, b);
const result: (() => void) & { foo: any } = assign(() => {}, { foo });

Expected behavior:

No error

Actual behavior:

Argument of type '{ foo: <T>() => void; }' is not assignable to parameter of type '(() => void) & { foo: any; }'.
  Type '{ foo: <T>() => void; }' is not assignable to type '() => void'.
    Type '{ foo: <T>() => void; }' provides no match for the signature '(): void'.

Playground Link:
https://www.typescriptlang.org/play/#src=const%20foo%20%3D%20%3CT%3E()%20%3D%3E%20%7B%7D%3B%0D%0Aconst%20assign%20%3D%20%3CT%2C%20U%3E(a%3A%20T%2C%20b%3A%20U)%20%3D%3E%20Object.assign(a%2C%20b)%3B%0D%0Aconst%20result%3A%20(()%20%3D%3E%20void)%20%26%20%7B%20foo%3A%20any%20%7D%20%3D%20assign(()%20%3D%3E%20%7B%7D%2C%20%7B%20foo%20%7D)%3B

Related Issues:


Removing <T> from foo makes this code valid.

@ark120202
Copy link
Author

Reproducible in 3.4.1

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Apr 9, 2019
@RyanCavanaugh
Copy link
Member

@ahejlsberg contextual typing strikes again? Moving the initializer to its own expression resolves its problem

const foo = <T,>() => {};
const assign = <T, U>(a: T, b: U) => Object.assign(a, b);
// No error
const res = assign(() => {}, { foo });
const result: (() => void) & { foo: any } = res;

@DanielRosenwasser DanielRosenwasser added this to the TypeScript 3.5.0 milestone Apr 9, 2019
@ahejlsberg
Copy link
Member

This is an effect of #29847. Previously we'd only make inferences to single naked type parameters in unions and intersections. We now infer to each naked type parameter. That works well for union types, but not for intersection types as this example illustrates. I think we should revert to the previous behavior for intersection types and only infer to multiple naked type parameters in union types.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript Fixed A PR has been merged for this issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants