mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Ensure resolved signature is cached before processing call errors (#49598)
This commit is contained in:
+11
-1
@@ -30736,6 +30736,16 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = getCandidateForOverloadFailure(node, candidates, args, !!candidatesOutArray, checkMode);
|
||||
// Preemptively cache the result; getResolvedSignature will do this after we return, but
|
||||
// we need to ensure that the result is present for the error checks below so that if
|
||||
// this signature is encountered again, we handle the circularity (rather than producing a
|
||||
// different result which may produce no errors and assert). Callers of getResolvedSignature
|
||||
// don't hit this issue because they only observe this result after it's had a chance to
|
||||
// be cached, but the error reporting code below executes before getResolvedSignature sets
|
||||
// resolvedSignature.
|
||||
getNodeLinks(node).resolvedSignature = result;
|
||||
|
||||
// No signatures were applicable. Now report errors based on the last applicable signature with
|
||||
// no arguments excluded from assignability checks.
|
||||
// If candidate is undefined, it means that no candidates had a suitable arity. In that case,
|
||||
@@ -30826,7 +30836,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
return getCandidateForOverloadFailure(node, candidates, args, !!candidatesOutArray, checkMode);
|
||||
return result;
|
||||
|
||||
function addImplementationSuccessElaboration(failed: Signature, diagnostic: Diagnostic) {
|
||||
const oldCandidatesForArgumentError = candidatesForArgumentError;
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
tests/cases/compiler/circularResolvedSignature.ts(11,9): error TS2322: Type 'string' is not assignable to type 'number'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/circularResolvedSignature.ts (1 errors) ====
|
||||
declare function useState<S>(initialState: (() => S)): [S, (s: S) => void];
|
||||
|
||||
type Data = Readonly<{
|
||||
value: number;
|
||||
foo: (arg: any) => void;
|
||||
bar: (arg: any) => void;
|
||||
}>;
|
||||
|
||||
export function Component() {
|
||||
const [state, setState] = useState<Data>(() => ({
|
||||
value: "string", // this should be a number
|
||||
~~~~~
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'number'.
|
||||
!!! related TS6500 tests/cases/compiler/circularResolvedSignature.ts:4:5: The expected type comes from property 'value' which is declared here on type 'Readonly<{ value: number; foo: (arg: any) => void; bar: (arg: any) => void; }>'
|
||||
foo: (arg) => setState(arg),
|
||||
bar: (arg) => setState(arg),
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
//// [circularResolvedSignature.ts]
|
||||
declare function useState<S>(initialState: (() => S)): [S, (s: S) => void];
|
||||
|
||||
type Data = Readonly<{
|
||||
value: number;
|
||||
foo: (arg: any) => void;
|
||||
bar: (arg: any) => void;
|
||||
}>;
|
||||
|
||||
export function Component() {
|
||||
const [state, setState] = useState<Data>(() => ({
|
||||
value: "string", // this should be a number
|
||||
foo: (arg) => setState(arg),
|
||||
bar: (arg) => setState(arg),
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
//// [circularResolvedSignature.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
exports.Component = void 0;
|
||||
function Component() {
|
||||
var _a = useState(function () { return ({
|
||||
value: "string",
|
||||
foo: function (arg) { return setState(arg); },
|
||||
bar: function (arg) { return setState(arg); }
|
||||
}); }), state = _a[0], setState = _a[1];
|
||||
}
|
||||
exports.Component = Component;
|
||||
@@ -0,0 +1,54 @@
|
||||
=== tests/cases/compiler/circularResolvedSignature.ts ===
|
||||
declare function useState<S>(initialState: (() => S)): [S, (s: S) => void];
|
||||
>useState : Symbol(useState, Decl(circularResolvedSignature.ts, 0, 0))
|
||||
>S : Symbol(S, Decl(circularResolvedSignature.ts, 0, 26))
|
||||
>initialState : Symbol(initialState, Decl(circularResolvedSignature.ts, 0, 29))
|
||||
>S : Symbol(S, Decl(circularResolvedSignature.ts, 0, 26))
|
||||
>S : Symbol(S, Decl(circularResolvedSignature.ts, 0, 26))
|
||||
>s : Symbol(s, Decl(circularResolvedSignature.ts, 0, 60))
|
||||
>S : Symbol(S, Decl(circularResolvedSignature.ts, 0, 26))
|
||||
|
||||
type Data = Readonly<{
|
||||
>Data : Symbol(Data, Decl(circularResolvedSignature.ts, 0, 75))
|
||||
>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
value: number;
|
||||
>value : Symbol(value, Decl(circularResolvedSignature.ts, 2, 22))
|
||||
|
||||
foo: (arg: any) => void;
|
||||
>foo : Symbol(foo, Decl(circularResolvedSignature.ts, 3, 18))
|
||||
>arg : Symbol(arg, Decl(circularResolvedSignature.ts, 4, 10))
|
||||
|
||||
bar: (arg: any) => void;
|
||||
>bar : Symbol(bar, Decl(circularResolvedSignature.ts, 4, 28))
|
||||
>arg : Symbol(arg, Decl(circularResolvedSignature.ts, 5, 10))
|
||||
|
||||
}>;
|
||||
|
||||
export function Component() {
|
||||
>Component : Symbol(Component, Decl(circularResolvedSignature.ts, 6, 3))
|
||||
|
||||
const [state, setState] = useState<Data>(() => ({
|
||||
>state : Symbol(state, Decl(circularResolvedSignature.ts, 9, 11))
|
||||
>setState : Symbol(setState, Decl(circularResolvedSignature.ts, 9, 17))
|
||||
>useState : Symbol(useState, Decl(circularResolvedSignature.ts, 0, 0))
|
||||
>Data : Symbol(Data, Decl(circularResolvedSignature.ts, 0, 75))
|
||||
|
||||
value: "string", // this should be a number
|
||||
>value : Symbol(value, Decl(circularResolvedSignature.ts, 9, 53))
|
||||
|
||||
foo: (arg) => setState(arg),
|
||||
>foo : Symbol(foo, Decl(circularResolvedSignature.ts, 10, 24))
|
||||
>arg : Symbol(arg, Decl(circularResolvedSignature.ts, 11, 14))
|
||||
>setState : Symbol(setState, Decl(circularResolvedSignature.ts, 9, 17))
|
||||
>arg : Symbol(arg, Decl(circularResolvedSignature.ts, 11, 14))
|
||||
|
||||
bar: (arg) => setState(arg),
|
||||
>bar : Symbol(bar, Decl(circularResolvedSignature.ts, 11, 36))
|
||||
>arg : Symbol(arg, Decl(circularResolvedSignature.ts, 12, 14))
|
||||
>setState : Symbol(setState, Decl(circularResolvedSignature.ts, 9, 17))
|
||||
>arg : Symbol(arg, Decl(circularResolvedSignature.ts, 12, 14))
|
||||
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
=== tests/cases/compiler/circularResolvedSignature.ts ===
|
||||
declare function useState<S>(initialState: (() => S)): [S, (s: S) => void];
|
||||
>useState : <S>(initialState: (() => S)) => [S, (s: S) => void]
|
||||
>initialState : () => S
|
||||
>s : S
|
||||
|
||||
type Data = Readonly<{
|
||||
>Data : Readonly<{ value: number; foo: (arg: any) => void; bar: (arg: any) => void; }>
|
||||
|
||||
value: number;
|
||||
>value : number
|
||||
|
||||
foo: (arg: any) => void;
|
||||
>foo : (arg: any) => void
|
||||
>arg : any
|
||||
|
||||
bar: (arg: any) => void;
|
||||
>bar : (arg: any) => void
|
||||
>arg : any
|
||||
|
||||
}>;
|
||||
|
||||
export function Component() {
|
||||
>Component : () => void
|
||||
|
||||
const [state, setState] = useState<Data>(() => ({
|
||||
>state : Readonly<{ value: number; foo: (arg: any) => void; bar: (arg: any) => void; }>
|
||||
>setState : (s: Readonly<{ value: number; foo: (arg: any) => void; bar: (arg: any) => void; }>) => void
|
||||
>useState<Data>(() => ({ value: "string", // this should be a number foo: (arg) => setState(arg), bar: (arg) => setState(arg), })) : [Readonly<{ value: number; foo: (arg: any) => void; bar: (arg: any) => void; }>, (s: Readonly<{ value: number; foo: (arg: any) => void; bar: (arg: any) => void; }>) => void]
|
||||
>useState : <S>(initialState: () => S) => [S, (s: S) => void]
|
||||
>() => ({ value: "string", // this should be a number foo: (arg) => setState(arg), bar: (arg) => setState(arg), }) : () => { value: string; foo: (arg: any) => void; bar: (arg: any) => void; }
|
||||
>({ value: "string", // this should be a number foo: (arg) => setState(arg), bar: (arg) => setState(arg), }) : { value: string; foo: (arg: any) => void; bar: (arg: any) => void; }
|
||||
>{ value: "string", // this should be a number foo: (arg) => setState(arg), bar: (arg) => setState(arg), } : { value: string; foo: (arg: any) => void; bar: (arg: any) => void; }
|
||||
|
||||
value: "string", // this should be a number
|
||||
>value : string
|
||||
>"string" : "string"
|
||||
|
||||
foo: (arg) => setState(arg),
|
||||
>foo : (arg: any) => void
|
||||
>(arg) => setState(arg) : (arg: any) => void
|
||||
>arg : any
|
||||
>setState(arg) : void
|
||||
>setState : (s: Readonly<{ value: number; foo: (arg: any) => void; bar: (arg: any) => void; }>) => void
|
||||
>arg : any
|
||||
|
||||
bar: (arg) => setState(arg),
|
||||
>bar : (arg: any) => void
|
||||
>(arg) => setState(arg) : (arg: any) => void
|
||||
>arg : any
|
||||
>setState(arg) : void
|
||||
>setState : (s: Readonly<{ value: number; foo: (arg: any) => void; bar: (arg: any) => void; }>) => void
|
||||
>arg : any
|
||||
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGenericSignatureArguments3.ts(32,19): error TS2345: Argument of type '(a1: (y: string) => string) => (n: Object) => number' is not assignable to parameter of type '(x: (a: string) => boolean) => (n: Object) => number'.
|
||||
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGenericSignatureArguments3.ts(32,19): error TS2345: Argument of type '(a1: (y: string) => string) => (n: Object) => 1' is not assignable to parameter of type '(x: (a: string) => boolean) => (n: Object) => 1'.
|
||||
Types of parameters 'a1' and 'x' are incompatible.
|
||||
Type 'boolean' is not assignable to type 'string'.
|
||||
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGenericSignatureArguments3.ts(33,69): error TS2345: Argument of type '(a2: (z: string) => boolean) => number' is not assignable to parameter of type '(x: (z: string) => boolean) => (n: Object) => number'.
|
||||
Type 'number' is not assignable to type '(n: Object) => number'.
|
||||
tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGenericSignatureArguments3.ts(33,69): error TS2345: Argument of type '(a2: (z: string) => boolean) => number' is not assignable to parameter of type '(x: (z: string) => boolean) => (n: Object) => 1'.
|
||||
Type 'number' is not assignable to type '(n: Object) => 1'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGenericSignatureArguments3.ts (2 errors) ====
|
||||
@@ -39,10 +39,10 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithGen
|
||||
var x: (a: string) => boolean;
|
||||
var r11 = foo2(x, (a1: (y: string) => string) => (n: Object) => 1, (a2: (z: string) => string) => 2); // error
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2345: Argument of type '(a1: (y: string) => string) => (n: Object) => number' is not assignable to parameter of type '(x: (a: string) => boolean) => (n: Object) => number'.
|
||||
!!! error TS2345: Argument of type '(a1: (y: string) => string) => (n: Object) => 1' is not assignable to parameter of type '(x: (a: string) => boolean) => (n: Object) => 1'.
|
||||
!!! error TS2345: Types of parameters 'a1' and 'x' are incompatible.
|
||||
!!! error TS2345: Type 'boolean' is not assignable to type 'string'.
|
||||
var r12 = foo2(x, (a1: (y: string) => boolean) => (n: Object) => 1, (a2: (z: string) => boolean) => 2); // error
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2345: Argument of type '(a2: (z: string) => boolean) => number' is not assignable to parameter of type '(x: (z: string) => boolean) => (n: Object) => number'.
|
||||
!!! error TS2345: Type 'number' is not assignable to type '(n: Object) => number'.
|
||||
!!! error TS2345: Argument of type '(a2: (z: string) => boolean) => number' is not assignable to parameter of type '(x: (z: string) => boolean) => (n: Object) => 1'.
|
||||
!!! error TS2345: Type 'number' is not assignable to type '(n: Object) => 1'.
|
||||
@@ -175,14 +175,14 @@ var x: (a: string) => boolean;
|
||||
>a : string
|
||||
|
||||
var r11 = foo2(x, (a1: (y: string) => string) => (n: Object) => 1, (a2: (z: string) => string) => 2); // error
|
||||
>r11 : (x: (a: string) => boolean) => (n: Object) => number
|
||||
>foo2(x, (a1: (y: string) => string) => (n: Object) => 1, (a2: (z: string) => string) => 2) : (x: (a: string) => boolean) => (n: Object) => number
|
||||
>r11 : (x: (a: string) => boolean) => (n: Object) => 1
|
||||
>foo2(x, (a1: (y: string) => string) => (n: Object) => 1, (a2: (z: string) => string) => 2) : (x: (a: string) => boolean) => (n: Object) => 1
|
||||
>foo2 : <T, U>(x: T, a: (x: T) => U, b: (x: T) => U) => (x: T) => U
|
||||
>x : (a: string) => boolean
|
||||
>(a1: (y: string) => string) => (n: Object) => 1 : (a1: (y: string) => string) => (n: Object) => number
|
||||
>(a1: (y: string) => string) => (n: Object) => 1 : (a1: (y: string) => string) => (n: Object) => 1
|
||||
>a1 : (y: string) => string
|
||||
>y : string
|
||||
>(n: Object) => 1 : (n: Object) => number
|
||||
>(n: Object) => 1 : (n: Object) => 1
|
||||
>n : Object
|
||||
>1 : 1
|
||||
>(a2: (z: string) => string) => 2 : (a2: (z: string) => string) => number
|
||||
@@ -191,14 +191,14 @@ var r11 = foo2(x, (a1: (y: string) => string) => (n: Object) => 1, (a2: (z: stri
|
||||
>2 : 2
|
||||
|
||||
var r12 = foo2(x, (a1: (y: string) => boolean) => (n: Object) => 1, (a2: (z: string) => boolean) => 2); // error
|
||||
>r12 : (x: (z: string) => boolean) => (n: Object) => number
|
||||
>foo2(x, (a1: (y: string) => boolean) => (n: Object) => 1, (a2: (z: string) => boolean) => 2) : (x: (z: string) => boolean) => (n: Object) => number
|
||||
>r12 : (x: (z: string) => boolean) => (n: Object) => 1
|
||||
>foo2(x, (a1: (y: string) => boolean) => (n: Object) => 1, (a2: (z: string) => boolean) => 2) : (x: (z: string) => boolean) => (n: Object) => 1
|
||||
>foo2 : <T, U>(x: T, a: (x: T) => U, b: (x: T) => U) => (x: T) => U
|
||||
>x : (a: string) => boolean
|
||||
>(a1: (y: string) => boolean) => (n: Object) => 1 : (a1: (y: string) => boolean) => (n: Object) => number
|
||||
>(a1: (y: string) => boolean) => (n: Object) => 1 : (a1: (y: string) => boolean) => (n: Object) => 1
|
||||
>a1 : (y: string) => boolean
|
||||
>y : string
|
||||
>(n: Object) => 1 : (n: Object) => number
|
||||
>(n: Object) => 1 : (n: Object) => 1
|
||||
>n : Object
|
||||
>1 : 1
|
||||
>(a2: (z: string) => boolean) => 2 : (a2: (z: string) => boolean) => number
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
declare function useState<S>(initialState: (() => S)): [S, (s: S) => void];
|
||||
|
||||
type Data = Readonly<{
|
||||
value: number;
|
||||
foo: (arg: any) => void;
|
||||
bar: (arg: any) => void;
|
||||
}>;
|
||||
|
||||
export function Component() {
|
||||
const [state, setState] = useState<Data>(() => ({
|
||||
value: "string", // this should be a number
|
||||
foo: (arg) => setState(arg),
|
||||
bar: (arg) => setState(arg),
|
||||
}));
|
||||
}
|
||||
Reference in New Issue
Block a user