Skip to content

Commit cf7b936

Browse files
authored
Fixed anyFunctionType leak (#64131)
1 parent f6b1667 commit cf7b936

5 files changed

Lines changed: 561 additions & 1 deletion

File tree

tsc/internal/checker/checker.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10365,7 +10365,9 @@ func (c *Checker) contextuallyCheckFunctionExpressionOrObjectLiteralMethod(node
1036510365
}
1036610366
}
1036710367
if contextualSignature != nil && c.getReturnTypeFromAnnotation(node) == nil && signature.resolvedReturnType == nil {
10368-
returnType := c.getReturnTypeFromBody(node, checkMode)
10368+
// resolvedReturnType is cached indefinitely, so the return type here has to be computed without CheckModeSkipContextSensitive;
10369+
// otherwise anyFunctionType could leak as part of the computed (and cached) return type.
10370+
returnType := c.getReturnTypeFromBody(node, checkMode&^CheckModeSkipContextSensitive)
1036910371
if signature.resolvedReturnType == nil {
1037010372
signature.resolvedReturnType = returnType
1037110373
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
contextualTypingGenericFunction2.ts(10,3): error TS2322: Type '<T>(params: T) => (a: boolean, b: unknown) => 0 | 1' is not assignable to type '(params: T) => (context: number, params: T) => number'.
2+
Type '(a: boolean, b: unknown) => 0 | 1' is not assignable to type '(context: number, params: T) => number'.
3+
Types of parameters 'a' and 'context' are incompatible.
4+
Type 'number' is not assignable to type 'boolean'.
5+
contextualTypingGenericFunction2.ts(18,3): error TS2322: Type '<T>(params: T) => (a: number, b: unknown) => boolean' is not assignable to type '(params: T) => (context: number, params: T) => number'.
6+
Type '(a: number, b: unknown) => boolean' is not assignable to type '(context: number, params: T) => number'.
7+
Type 'boolean' is not assignable to type 'number'.
8+
contextualTypingGenericFunction2.ts(26,3): error TS2322: Type '<T>(params: T) => (a: number, b: unknown) => boolean' is not assignable to type '(params: T) => (context: number, params: T) => number'.
9+
Type '(a: number, b: unknown) => boolean' is not assignable to type '(context: number, params: T) => number'.
10+
Type 'boolean' is not assignable to type 'number'.
11+
contextualTypingGenericFunction2.ts(39,3): error TS2322: Type '<T>(params: T) => (a: boolean, b: unknown) => 0 | 1' is not assignable to type '(params: unknown) => (context: number, params: unknown) => number'.
12+
Type '(a: boolean, b: unknown) => 0 | 1' is not assignable to type '(context: number, params: unknown) => number'.
13+
Types of parameters 'a' and 'context' are incompatible.
14+
Type 'number' is not assignable to type 'boolean'.
15+
contextualTypingGenericFunction2.ts(47,3): error TS2322: Type '<T>(params: T) => (a: number, b: unknown) => boolean' is not assignable to type '(params: unknown) => (context: number, params: unknown) => number'.
16+
Type '(a: number, b: unknown) => boolean' is not assignable to type '(context: number, params: unknown) => number'.
17+
Type 'boolean' is not assignable to type 'number'.
18+
contextualTypingGenericFunction2.ts(55,3): error TS2322: Type '<T>(params: T) => (a: number, b: unknown) => boolean' is not assignable to type '(params: unknown) => (context: number, params: unknown) => number'.
19+
Type '(a: number, b: unknown) => boolean' is not assignable to type '(context: number, params: unknown) => number'.
20+
Type 'boolean' is not assignable to type 'number'.
21+
22+
23+
==== contextualTypingGenericFunction2.ts (6 errors) ====
24+
// https://github.com/microsoft/TypeScript/issues/61979
25+
26+
declare function fn<P>(config: {
27+
callback: (params: P) => (context: number, params: P) => number;
28+
unrelated?: (arg: string) => void;
29+
}): (params: P) => number;
30+
31+
// should error
32+
export const result1 = fn({
33+
callback: <T,>(params: T) => {
34+
~~~~~~~~
35+
!!! error TS2322: Type '<T>(params: T) => (a: boolean, b: unknown) => 0 | 1' is not assignable to type '(params: T) => (context: number, params: T) => number'.
36+
!!! error TS2322: Type '(a: boolean, b: unknown) => 0 | 1' is not assignable to type '(context: number, params: T) => number'.
37+
!!! error TS2322: Types of parameters 'a' and 'context' are incompatible.
38+
!!! error TS2322: Type 'number' is not assignable to type 'boolean'.
39+
!!! related TS6500 contextualTypingGenericFunction2.ts:4:3: The expected type comes from property 'callback' which is declared here on type '{ callback: (params: T) => (context: number, params: T) => number; unrelated?: ((arg: string) => void) | undefined; }'
40+
return (a: boolean, b) => (a ? 1 : 0);
41+
},
42+
unrelated: (_) => {},
43+
});
44+
45+
// should error
46+
export const result2 = fn({
47+
callback: <T,>(params: T) => {
48+
~~~~~~~~
49+
!!! error TS2322: Type '<T>(params: T) => (a: number, b: unknown) => boolean' is not assignable to type '(params: T) => (context: number, params: T) => number'.
50+
!!! error TS2322: Type '(a: number, b: unknown) => boolean' is not assignable to type '(context: number, params: T) => number'.
51+
!!! error TS2322: Type 'boolean' is not assignable to type 'number'.
52+
!!! related TS6500 contextualTypingGenericFunction2.ts:4:3: The expected type comes from property 'callback' which is declared here on type '{ callback: (params: T) => (context: number, params: T) => number; unrelated?: ((arg: string) => void) | undefined; }'
53+
return (a, b): boolean => true;
54+
},
55+
unrelated: (_) => {},
56+
});
57+
58+
// should error
59+
export const result3 = fn({
60+
callback: <T,>(params: T) => {
61+
~~~~~~~~
62+
!!! error TS2322: Type '<T>(params: T) => (a: number, b: unknown) => boolean' is not assignable to type '(params: T) => (context: number, params: T) => number'.
63+
!!! error TS2322: Type '(a: number, b: unknown) => boolean' is not assignable to type '(context: number, params: T) => number'.
64+
!!! error TS2322: Type 'boolean' is not assignable to type 'number'.
65+
!!! related TS6500 contextualTypingGenericFunction2.ts:4:3: The expected type comes from property 'callback' which is declared here on type '{ callback: (params: T) => (context: number, params: T) => number; unrelated?: ((arg: string) => void) | undefined; }'
66+
return (a, b) => true;
67+
},
68+
unrelated: (_) => {},
69+
});
70+
71+
declare function fn2<P>(config: {
72+
callback: (params: P) => (context: number, params: P) => number;
73+
unrelated?: (arg: string) => void;
74+
}): any;
75+
76+
// should error
77+
export const result4 = fn2({
78+
callback: <T,>(params: T) => {
79+
~~~~~~~~
80+
!!! error TS2322: Type '<T>(params: T) => (a: boolean, b: unknown) => 0 | 1' is not assignable to type '(params: unknown) => (context: number, params: unknown) => number'.
81+
!!! error TS2322: Type '(a: boolean, b: unknown) => 0 | 1' is not assignable to type '(context: number, params: unknown) => number'.
82+
!!! error TS2322: Types of parameters 'a' and 'context' are incompatible.
83+
!!! error TS2322: Type 'number' is not assignable to type 'boolean'.
84+
!!! related TS6500 contextualTypingGenericFunction2.ts:33:3: The expected type comes from property 'callback' which is declared here on type '{ callback: (params: unknown) => (context: number, params: unknown) => number; unrelated?: ((arg: string) => void) | undefined; }'
85+
return (a: boolean, b) => (a ? 1 : 0);
86+
},
87+
unrelated: (_) => {},
88+
});
89+
90+
// should error
91+
export const result5 = fn2({
92+
callback: <T,>(params: T) => {
93+
~~~~~~~~
94+
!!! error TS2322: Type '<T>(params: T) => (a: number, b: unknown) => boolean' is not assignable to type '(params: unknown) => (context: number, params: unknown) => number'.
95+
!!! error TS2322: Type '(a: number, b: unknown) => boolean' is not assignable to type '(context: number, params: unknown) => number'.
96+
!!! error TS2322: Type 'boolean' is not assignable to type 'number'.
97+
!!! related TS6500 contextualTypingGenericFunction2.ts:33:3: The expected type comes from property 'callback' which is declared here on type '{ callback: (params: unknown) => (context: number, params: unknown) => number; unrelated?: ((arg: string) => void) | undefined; }'
98+
return (a, b): boolean => true;
99+
},
100+
unrelated: (_) => {},
101+
});
102+
103+
// should error
104+
export const result6 = fn2({
105+
callback: <T,>(params: T) => {
106+
~~~~~~~~
107+
!!! error TS2322: Type '<T>(params: T) => (a: number, b: unknown) => boolean' is not assignable to type '(params: unknown) => (context: number, params: unknown) => number'.
108+
!!! error TS2322: Type '(a: number, b: unknown) => boolean' is not assignable to type '(context: number, params: unknown) => number'.
109+
!!! error TS2322: Type 'boolean' is not assignable to type 'number'.
110+
!!! related TS6500 contextualTypingGenericFunction2.ts:33:3: The expected type comes from property 'callback' which is declared here on type '{ callback: (params: unknown) => (context: number, params: unknown) => number; unrelated?: ((arg: string) => void) | undefined; }'
111+
return (a, b) => true;
112+
},
113+
unrelated: (_) => {},
114+
});
115+
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
//// [tests/cases/compiler/contextualTypingGenericFunction2.ts] ////
2+
3+
=== contextualTypingGenericFunction2.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/61979
5+
6+
declare function fn<P>(config: {
7+
>fn : Symbol(fn, Decl(contextualTypingGenericFunction2.ts, 0, 0))
8+
>P : Symbol(P, Decl(contextualTypingGenericFunction2.ts, 2, 20))
9+
>config : Symbol(config, Decl(contextualTypingGenericFunction2.ts, 2, 23))
10+
11+
callback: (params: P) => (context: number, params: P) => number;
12+
>callback : Symbol(callback, Decl(contextualTypingGenericFunction2.ts, 2, 32))
13+
>params : Symbol(params, Decl(contextualTypingGenericFunction2.ts, 3, 13))
14+
>P : Symbol(P, Decl(contextualTypingGenericFunction2.ts, 2, 20))
15+
>context : Symbol(context, Decl(contextualTypingGenericFunction2.ts, 3, 28))
16+
>params : Symbol(params, Decl(contextualTypingGenericFunction2.ts, 3, 44))
17+
>P : Symbol(P, Decl(contextualTypingGenericFunction2.ts, 2, 20))
18+
19+
unrelated?: (arg: string) => void;
20+
>unrelated : Symbol(unrelated, Decl(contextualTypingGenericFunction2.ts, 3, 66))
21+
>arg : Symbol(arg, Decl(contextualTypingGenericFunction2.ts, 4, 15))
22+
23+
}): (params: P) => number;
24+
>params : Symbol(params, Decl(contextualTypingGenericFunction2.ts, 5, 5))
25+
>P : Symbol(P, Decl(contextualTypingGenericFunction2.ts, 2, 20))
26+
27+
// should error
28+
export const result1 = fn({
29+
>result1 : Symbol(result1, Decl(contextualTypingGenericFunction2.ts, 8, 12))
30+
>fn : Symbol(fn, Decl(contextualTypingGenericFunction2.ts, 0, 0))
31+
32+
callback: <T,>(params: T) => {
33+
>callback : Symbol(callback, Decl(contextualTypingGenericFunction2.ts, 8, 27))
34+
>T : Symbol(T, Decl(contextualTypingGenericFunction2.ts, 9, 13))
35+
>params : Symbol(params, Decl(contextualTypingGenericFunction2.ts, 9, 17))
36+
>T : Symbol(T, Decl(contextualTypingGenericFunction2.ts, 9, 13))
37+
38+
return (a: boolean, b) => (a ? 1 : 0);
39+
>a : Symbol(a, Decl(contextualTypingGenericFunction2.ts, 10, 12))
40+
>b : Symbol(b, Decl(contextualTypingGenericFunction2.ts, 10, 23))
41+
>a : Symbol(a, Decl(contextualTypingGenericFunction2.ts, 10, 12))
42+
43+
},
44+
unrelated: (_) => {},
45+
>unrelated : Symbol(unrelated, Decl(contextualTypingGenericFunction2.ts, 11, 4))
46+
>_ : Symbol(_, Decl(contextualTypingGenericFunction2.ts, 12, 14))
47+
48+
});
49+
50+
// should error
51+
export const result2 = fn({
52+
>result2 : Symbol(result2, Decl(contextualTypingGenericFunction2.ts, 16, 12))
53+
>fn : Symbol(fn, Decl(contextualTypingGenericFunction2.ts, 0, 0))
54+
55+
callback: <T,>(params: T) => {
56+
>callback : Symbol(callback, Decl(contextualTypingGenericFunction2.ts, 16, 27))
57+
>T : Symbol(T, Decl(contextualTypingGenericFunction2.ts, 17, 13))
58+
>params : Symbol(params, Decl(contextualTypingGenericFunction2.ts, 17, 17))
59+
>T : Symbol(T, Decl(contextualTypingGenericFunction2.ts, 17, 13))
60+
61+
return (a, b): boolean => true;
62+
>a : Symbol(a, Decl(contextualTypingGenericFunction2.ts, 18, 12))
63+
>b : Symbol(b, Decl(contextualTypingGenericFunction2.ts, 18, 14))
64+
65+
},
66+
unrelated: (_) => {},
67+
>unrelated : Symbol(unrelated, Decl(contextualTypingGenericFunction2.ts, 19, 4))
68+
>_ : Symbol(_, Decl(contextualTypingGenericFunction2.ts, 20, 14))
69+
70+
});
71+
72+
// should error
73+
export const result3 = fn({
74+
>result3 : Symbol(result3, Decl(contextualTypingGenericFunction2.ts, 24, 12))
75+
>fn : Symbol(fn, Decl(contextualTypingGenericFunction2.ts, 0, 0))
76+
77+
callback: <T,>(params: T) => {
78+
>callback : Symbol(callback, Decl(contextualTypingGenericFunction2.ts, 24, 27))
79+
>T : Symbol(T, Decl(contextualTypingGenericFunction2.ts, 25, 13))
80+
>params : Symbol(params, Decl(contextualTypingGenericFunction2.ts, 25, 17))
81+
>T : Symbol(T, Decl(contextualTypingGenericFunction2.ts, 25, 13))
82+
83+
return (a, b) => true;
84+
>a : Symbol(a, Decl(contextualTypingGenericFunction2.ts, 26, 12))
85+
>b : Symbol(b, Decl(contextualTypingGenericFunction2.ts, 26, 14))
86+
87+
},
88+
unrelated: (_) => {},
89+
>unrelated : Symbol(unrelated, Decl(contextualTypingGenericFunction2.ts, 27, 4))
90+
>_ : Symbol(_, Decl(contextualTypingGenericFunction2.ts, 28, 14))
91+
92+
});
93+
94+
declare function fn2<P>(config: {
95+
>fn2 : Symbol(fn2, Decl(contextualTypingGenericFunction2.ts, 29, 3))
96+
>P : Symbol(P, Decl(contextualTypingGenericFunction2.ts, 31, 21))
97+
>config : Symbol(config, Decl(contextualTypingGenericFunction2.ts, 31, 24))
98+
99+
callback: (params: P) => (context: number, params: P) => number;
100+
>callback : Symbol(callback, Decl(contextualTypingGenericFunction2.ts, 31, 33))
101+
>params : Symbol(params, Decl(contextualTypingGenericFunction2.ts, 32, 13))
102+
>P : Symbol(P, Decl(contextualTypingGenericFunction2.ts, 31, 21))
103+
>context : Symbol(context, Decl(contextualTypingGenericFunction2.ts, 32, 28))
104+
>params : Symbol(params, Decl(contextualTypingGenericFunction2.ts, 32, 44))
105+
>P : Symbol(P, Decl(contextualTypingGenericFunction2.ts, 31, 21))
106+
107+
unrelated?: (arg: string) => void;
108+
>unrelated : Symbol(unrelated, Decl(contextualTypingGenericFunction2.ts, 32, 66))
109+
>arg : Symbol(arg, Decl(contextualTypingGenericFunction2.ts, 33, 15))
110+
111+
}): any;
112+
113+
// should error
114+
export const result4 = fn2({
115+
>result4 : Symbol(result4, Decl(contextualTypingGenericFunction2.ts, 37, 12))
116+
>fn2 : Symbol(fn2, Decl(contextualTypingGenericFunction2.ts, 29, 3))
117+
118+
callback: <T,>(params: T) => {
119+
>callback : Symbol(callback, Decl(contextualTypingGenericFunction2.ts, 37, 28))
120+
>T : Symbol(T, Decl(contextualTypingGenericFunction2.ts, 38, 13))
121+
>params : Symbol(params, Decl(contextualTypingGenericFunction2.ts, 38, 17))
122+
>T : Symbol(T, Decl(contextualTypingGenericFunction2.ts, 38, 13))
123+
124+
return (a: boolean, b) => (a ? 1 : 0);
125+
>a : Symbol(a, Decl(contextualTypingGenericFunction2.ts, 39, 12))
126+
>b : Symbol(b, Decl(contextualTypingGenericFunction2.ts, 39, 23))
127+
>a : Symbol(a, Decl(contextualTypingGenericFunction2.ts, 39, 12))
128+
129+
},
130+
unrelated: (_) => {},
131+
>unrelated : Symbol(unrelated, Decl(contextualTypingGenericFunction2.ts, 40, 4))
132+
>_ : Symbol(_, Decl(contextualTypingGenericFunction2.ts, 41, 14))
133+
134+
});
135+
136+
// should error
137+
export const result5 = fn2({
138+
>result5 : Symbol(result5, Decl(contextualTypingGenericFunction2.ts, 45, 12))
139+
>fn2 : Symbol(fn2, Decl(contextualTypingGenericFunction2.ts, 29, 3))
140+
141+
callback: <T,>(params: T) => {
142+
>callback : Symbol(callback, Decl(contextualTypingGenericFunction2.ts, 45, 28))
143+
>T : Symbol(T, Decl(contextualTypingGenericFunction2.ts, 46, 13))
144+
>params : Symbol(params, Decl(contextualTypingGenericFunction2.ts, 46, 17))
145+
>T : Symbol(T, Decl(contextualTypingGenericFunction2.ts, 46, 13))
146+
147+
return (a, b): boolean => true;
148+
>a : Symbol(a, Decl(contextualTypingGenericFunction2.ts, 47, 12))
149+
>b : Symbol(b, Decl(contextualTypingGenericFunction2.ts, 47, 14))
150+
151+
},
152+
unrelated: (_) => {},
153+
>unrelated : Symbol(unrelated, Decl(contextualTypingGenericFunction2.ts, 48, 4))
154+
>_ : Symbol(_, Decl(contextualTypingGenericFunction2.ts, 49, 14))
155+
156+
});
157+
158+
// should error
159+
export const result6 = fn2({
160+
>result6 : Symbol(result6, Decl(contextualTypingGenericFunction2.ts, 53, 12))
161+
>fn2 : Symbol(fn2, Decl(contextualTypingGenericFunction2.ts, 29, 3))
162+
163+
callback: <T,>(params: T) => {
164+
>callback : Symbol(callback, Decl(contextualTypingGenericFunction2.ts, 53, 28))
165+
>T : Symbol(T, Decl(contextualTypingGenericFunction2.ts, 54, 13))
166+
>params : Symbol(params, Decl(contextualTypingGenericFunction2.ts, 54, 17))
167+
>T : Symbol(T, Decl(contextualTypingGenericFunction2.ts, 54, 13))
168+
169+
return (a, b) => true;
170+
>a : Symbol(a, Decl(contextualTypingGenericFunction2.ts, 55, 12))
171+
>b : Symbol(b, Decl(contextualTypingGenericFunction2.ts, 55, 14))
172+
173+
},
174+
unrelated: (_) => {},
175+
>unrelated : Symbol(unrelated, Decl(contextualTypingGenericFunction2.ts, 56, 4))
176+
>_ : Symbol(_, Decl(contextualTypingGenericFunction2.ts, 57, 14))
177+
178+
});
179+

0 commit comments

Comments
 (0)