-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Refrain from attempting to perform parameter fixing on a generic signature multiple times #43835
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30345,7 +30345,14 @@ namespace ts { | |
} | ||
|
||
function assignContextualParameterTypes(signature: Signature, context: Signature) { | ||
signature.typeParameters = context.typeParameters; | ||
if (context.typeParameters) { | ||
if (!signature.typeParameters) { | ||
signature.typeParameters = context.typeParameters; | ||
} | ||
else { | ||
return; // This signature has already has a contextual inference performed and cached on it! | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Double-checking my understanding; is this correct?: it's enough to bail after seeing that typeParameters is set, because a normal run of this function sets both typeParameters and parameters. So you don't have to check parameters as well. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Aye. Moreover, if a function somehow has type parameters set already, but not parameters, fixing parameters which contain a separate set of type parameters would be bad, too. (It'd be like the inverse of the original issue that caused the report) |
||
} | ||
} | ||
if (context.thisParameter) { | ||
const parameter = signature.thisParameter; | ||
if (!parameter || parameter.valueDeclaration && !(<ParameterDeclaration>parameter.valueDeclaration).type) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
//// [contextuallyTypedGenericAssignment.ts] | ||
function foo<A extends any[]>( | ||
arg: <T extends { a: number }>(t: T, ...rest: A) => number | ||
) { } | ||
|
||
foo((t, u: number) => t.a) | ||
|
||
//// [contextuallyTypedGenericAssignment.js] | ||
function foo(arg) { } | ||
foo(function (t, u) { return t.a; }); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
=== tests/cases/compiler/contextuallyTypedGenericAssignment.ts === | ||
function foo<A extends any[]>( | ||
>foo : Symbol(foo, Decl(contextuallyTypedGenericAssignment.ts, 0, 0)) | ||
>A : Symbol(A, Decl(contextuallyTypedGenericAssignment.ts, 0, 13)) | ||
|
||
arg: <T extends { a: number }>(t: T, ...rest: A) => number | ||
>arg : Symbol(arg, Decl(contextuallyTypedGenericAssignment.ts, 0, 30)) | ||
>T : Symbol(T, Decl(contextuallyTypedGenericAssignment.ts, 1, 10)) | ||
>a : Symbol(a, Decl(contextuallyTypedGenericAssignment.ts, 1, 21)) | ||
>t : Symbol(t, Decl(contextuallyTypedGenericAssignment.ts, 1, 35)) | ||
>T : Symbol(T, Decl(contextuallyTypedGenericAssignment.ts, 1, 10)) | ||
>rest : Symbol(rest, Decl(contextuallyTypedGenericAssignment.ts, 1, 40)) | ||
>A : Symbol(A, Decl(contextuallyTypedGenericAssignment.ts, 0, 13)) | ||
|
||
) { } | ||
|
||
foo((t, u: number) => t.a) | ||
>foo : Symbol(foo, Decl(contextuallyTypedGenericAssignment.ts, 0, 0)) | ||
>t : Symbol(t, Decl(contextuallyTypedGenericAssignment.ts, 4, 5)) | ||
>u : Symbol(u, Decl(contextuallyTypedGenericAssignment.ts, 4, 7)) | ||
>t.a : Symbol(a, Decl(contextuallyTypedGenericAssignment.ts, 1, 21)) | ||
>t : Symbol(t, Decl(contextuallyTypedGenericAssignment.ts, 4, 5)) | ||
>a : Symbol(a, Decl(contextuallyTypedGenericAssignment.ts, 1, 21)) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
=== tests/cases/compiler/contextuallyTypedGenericAssignment.ts === | ||
function foo<A extends any[]>( | ||
>foo : <A extends any[]>(arg: <T extends { a: number; }>(t: T, ...rest: A) => number) => void | ||
|
||
arg: <T extends { a: number }>(t: T, ...rest: A) => number | ||
>arg : <T extends { a: number; }>(t: T, ...rest: A) => number | ||
>a : number | ||
>t : T | ||
>rest : A | ||
|
||
) { } | ||
|
||
foo((t, u: number) => t.a) | ||
>foo((t, u: number) => t.a) : void | ||
>foo : <A extends any[]>(arg: <T extends { a: number; }>(t: T, ...rest: A) => number) => void | ||
>(t, u: number) => t.a : <T extends { a: number; }>(t: T, u: number) => number | ||
>t : T | ||
>u : number | ||
>t.a : number | ||
>t : T | ||
>a : number | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
function foo<A extends any[]>( | ||
arg: <T extends { a: number }>(t: T, ...rest: A) => number | ||
) { } | ||
|
||
foo((t, u: number) => t.a) |
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.
Is context.typeParameters ever
undefined
? Was that the bug here?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.
I mean, I don't want to overwrite a signature's type parameters with
undefined
, and there's no reason to do anything if they're bothundefined
.