mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 08:11:30 -06:00
Fixed an issue with an incorrect resolved signature being cached/returned sometimes for signatures depending on the contextual type/outer inference (#52146)
This commit is contained in:
parent
916f9b7344
commit
218180ded2
@ -33984,10 +33984,18 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
return cached;
|
||||
}
|
||||
links.resolvedSignature = resolvingSignature;
|
||||
const result = resolveSignature(node, candidatesOutArray, checkMode || CheckMode.Normal);
|
||||
let result = resolveSignature(node, candidatesOutArray, checkMode || CheckMode.Normal);
|
||||
// When CheckMode.SkipGenericFunctions is set we use resolvingSignature to indicate that call
|
||||
// resolution should be deferred.
|
||||
if (result !== resolvingSignature) {
|
||||
// if the signature resolution originated on a node that itself depends on the contextual type
|
||||
// then it's possible that the resolved signature might not be the same as the one that would be computed in source order
|
||||
// since resolving such signature leads to resolving the potential outer signature, its arguments and thus the very same signature
|
||||
// it's possible that this inner resolution sets the resolvedSignature first.
|
||||
// In such a case we ignore the local result and reuse the correct one that was cached.
|
||||
if (links.resolvedSignature !== resolvingSignature) {
|
||||
result = links.resolvedSignature;
|
||||
}
|
||||
// If signature resolution originated in control flow type analysis (for example to compute the
|
||||
// assigned type in a flow assignment) we don't cache the result as it may be based on temporary
|
||||
// types from the control flow analysis.
|
||||
|
||||
22
tests/cases/fourslash/quickInfoNestedGenericCalls.ts
Normal file
22
tests/cases/fourslash/quickInfoNestedGenericCalls.ts
Normal file
@ -0,0 +1,22 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
// @strict: true
|
||||
//// /*1*/m({ foo: /*2*/$("foo") });
|
||||
//// m({ foo: /*3*/$("foo") });
|
||||
//// declare const m: <S extends string>(s: { [_ in S]: { $: NoInfer<S> } }) => void
|
||||
//// declare const $: <S, T extends S>(s: T) => { $: S }
|
||||
//// type NoInfer<T> = [T][T extends any ? 0 : never];
|
||||
|
||||
verify.quickInfoAt("1", `const m: <"foo">(s: {
|
||||
foo: {
|
||||
$: "foo";
|
||||
};
|
||||
}) => void`);
|
||||
|
||||
// the exact generic type params are not important in this test (they could change with changes to the inference algorithm)
|
||||
// it's important though that they both display the same types
|
||||
verify.quickInfoAt("2", `const $: <unknown, string>(s: string) => {
|
||||
$: unknown;
|
||||
}`);
|
||||
verify.quickInfoAt("3", `const $: <unknown, string>(s: string) => {
|
||||
$: unknown;
|
||||
}`);
|
||||
Loading…
x
Reference in New Issue
Block a user