Skip to content

Commit 0c2c58c

Browse files
authored
Create returnOnlySignature only when inferences will possibly be made (#35173)
* Create returnOnlySignature only when inferences will possibly be made * Add regression test * Accept new baselines
1 parent 0c17476 commit 0c2c58c

5 files changed

+492
-9
lines changed

src/compiler/checker.ts

+13-9
Original file line numberDiff line numberDiff line change
@@ -26129,15 +26129,19 @@ namespace ts {
2612926129
if (checkMode && checkMode & CheckMode.SkipContextSensitive && isContextSensitive(node)) {
2613026130
// Skip parameters, return signature with return type that retains noncontextual parts so inferences can still be drawn in an early stage
2613126131
if (!getEffectiveReturnTypeNode(node) && hasContextSensitiveReturnExpression(node)) {
26132-
const links = getNodeLinks(node);
26133-
if (links.contextFreeType) {
26134-
return links.contextFreeType;
26135-
}
26136-
const returnType = getReturnTypeFromBody(node, checkMode);
26137-
const returnOnlySignature = createSignature(undefined, undefined, undefined, emptyArray, returnType, /*resolvedTypePredicate*/ undefined, 0, SignatureFlags.None);
26138-
const returnOnlyType = createAnonymousType(node.symbol, emptySymbols, [returnOnlySignature], emptyArray, undefined, undefined);
26139-
returnOnlyType.objectFlags |= ObjectFlags.NonInferrableType;
26140-
return links.contextFreeType = returnOnlyType;
26132+
// Return plain anyFunctionType if there is no possibility we'll make inferences from the return type
26133+
const contextualSignature = getContextualSignature(node);
26134+
if (contextualSignature && couldContainTypeVariables(getReturnTypeOfSignature(contextualSignature))) {
26135+
const links = getNodeLinks(node);
26136+
if (links.contextFreeType) {
26137+
return links.contextFreeType;
26138+
}
26139+
const returnType = getReturnTypeFromBody(node, checkMode);
26140+
const returnOnlySignature = createSignature(undefined, undefined, undefined, emptyArray, returnType, /*resolvedTypePredicate*/ undefined, 0, SignatureFlags.None);
26141+
const returnOnlyType = createAnonymousType(node.symbol, emptySymbols, [returnOnlySignature], emptyArray, undefined, undefined);
26142+
returnOnlyType.objectFlags |= ObjectFlags.NonInferrableType;
26143+
return links.contextFreeType = returnOnlyType;
26144+
}
2614126145
}
2614226146
return anyFunctionType;
2614326147
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
//// [contextSensitiveReturnTypeInference.ts]
2+
// Repro from #34849
3+
4+
interface IData {
5+
bar: boolean
6+
}
7+
8+
declare function test<TDependencies>(
9+
getter: (deps: TDependencies, data: IData) => any,
10+
deps: TDependencies,
11+
): any
12+
13+
const DEPS = {
14+
foo: 1
15+
}
16+
17+
test(
18+
(deps, data) => ({
19+
fn1: function() { return deps.foo },
20+
fn2: data.bar
21+
}),
22+
DEPS
23+
);
24+
25+
test(
26+
(deps: typeof DEPS, data) => ({
27+
fn1: function() { return deps.foo },
28+
fn2: data.bar
29+
}),
30+
DEPS
31+
);
32+
33+
test(
34+
(deps, data) => ({
35+
fn1: () => deps.foo,
36+
fn2: data.bar
37+
}),
38+
DEPS
39+
);
40+
41+
test(
42+
(deps, data) => {
43+
return {
44+
fn1() { return deps.foo },
45+
fn2: data.bar
46+
}
47+
},
48+
DEPS
49+
);
50+
51+
test(
52+
(deps) => ({
53+
fn1() { return deps.foo },
54+
fn2: 1
55+
}),
56+
DEPS
57+
);
58+
59+
60+
//// [contextSensitiveReturnTypeInference.js]
61+
"use strict";
62+
// Repro from #34849
63+
var DEPS = {
64+
foo: 1
65+
};
66+
test(function (deps, data) { return ({
67+
fn1: function () { return deps.foo; },
68+
fn2: data.bar
69+
}); }, DEPS);
70+
test(function (deps, data) { return ({
71+
fn1: function () { return deps.foo; },
72+
fn2: data.bar
73+
}); }, DEPS);
74+
test(function (deps, data) { return ({
75+
fn1: function () { return deps.foo; },
76+
fn2: data.bar
77+
}); }, DEPS);
78+
test(function (deps, data) {
79+
return {
80+
fn1: function () { return deps.foo; },
81+
fn2: data.bar
82+
};
83+
}, DEPS);
84+
test(function (deps) { return ({
85+
fn1: function () { return deps.foo; },
86+
fn2: 1
87+
}); }, DEPS);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
=== tests/cases/compiler/contextSensitiveReturnTypeInference.ts ===
2+
// Repro from #34849
3+
4+
interface IData {
5+
>IData : Symbol(IData, Decl(contextSensitiveReturnTypeInference.ts, 0, 0))
6+
7+
bar: boolean
8+
>bar : Symbol(IData.bar, Decl(contextSensitiveReturnTypeInference.ts, 2, 17))
9+
}
10+
11+
declare function test<TDependencies>(
12+
>test : Symbol(test, Decl(contextSensitiveReturnTypeInference.ts, 4, 1))
13+
>TDependencies : Symbol(TDependencies, Decl(contextSensitiveReturnTypeInference.ts, 6, 22))
14+
15+
getter: (deps: TDependencies, data: IData) => any,
16+
>getter : Symbol(getter, Decl(contextSensitiveReturnTypeInference.ts, 6, 37))
17+
>deps : Symbol(deps, Decl(contextSensitiveReturnTypeInference.ts, 7, 11))
18+
>TDependencies : Symbol(TDependencies, Decl(contextSensitiveReturnTypeInference.ts, 6, 22))
19+
>data : Symbol(data, Decl(contextSensitiveReturnTypeInference.ts, 7, 31))
20+
>IData : Symbol(IData, Decl(contextSensitiveReturnTypeInference.ts, 0, 0))
21+
22+
deps: TDependencies,
23+
>deps : Symbol(deps, Decl(contextSensitiveReturnTypeInference.ts, 7, 52))
24+
>TDependencies : Symbol(TDependencies, Decl(contextSensitiveReturnTypeInference.ts, 6, 22))
25+
26+
): any
27+
28+
const DEPS = {
29+
>DEPS : Symbol(DEPS, Decl(contextSensitiveReturnTypeInference.ts, 11, 5))
30+
31+
foo: 1
32+
>foo : Symbol(foo, Decl(contextSensitiveReturnTypeInference.ts, 11, 14))
33+
}
34+
35+
test(
36+
>test : Symbol(test, Decl(contextSensitiveReturnTypeInference.ts, 4, 1))
37+
38+
(deps, data) => ({
39+
>deps : Symbol(deps, Decl(contextSensitiveReturnTypeInference.ts, 16, 3))
40+
>data : Symbol(data, Decl(contextSensitiveReturnTypeInference.ts, 16, 8))
41+
42+
fn1: function() { return deps.foo },
43+
>fn1 : Symbol(fn1, Decl(contextSensitiveReturnTypeInference.ts, 16, 20))
44+
>deps.foo : Symbol(foo, Decl(contextSensitiveReturnTypeInference.ts, 11, 14))
45+
>deps : Symbol(deps, Decl(contextSensitiveReturnTypeInference.ts, 16, 3))
46+
>foo : Symbol(foo, Decl(contextSensitiveReturnTypeInference.ts, 11, 14))
47+
48+
fn2: data.bar
49+
>fn2 : Symbol(fn2, Decl(contextSensitiveReturnTypeInference.ts, 17, 40))
50+
>data.bar : Symbol(IData.bar, Decl(contextSensitiveReturnTypeInference.ts, 2, 17))
51+
>data : Symbol(data, Decl(contextSensitiveReturnTypeInference.ts, 16, 8))
52+
>bar : Symbol(IData.bar, Decl(contextSensitiveReturnTypeInference.ts, 2, 17))
53+
54+
}),
55+
DEPS
56+
>DEPS : Symbol(DEPS, Decl(contextSensitiveReturnTypeInference.ts, 11, 5))
57+
58+
);
59+
60+
test(
61+
>test : Symbol(test, Decl(contextSensitiveReturnTypeInference.ts, 4, 1))
62+
63+
(deps: typeof DEPS, data) => ({
64+
>deps : Symbol(deps, Decl(contextSensitiveReturnTypeInference.ts, 24, 3))
65+
>DEPS : Symbol(DEPS, Decl(contextSensitiveReturnTypeInference.ts, 11, 5))
66+
>data : Symbol(data, Decl(contextSensitiveReturnTypeInference.ts, 24, 21))
67+
68+
fn1: function() { return deps.foo },
69+
>fn1 : Symbol(fn1, Decl(contextSensitiveReturnTypeInference.ts, 24, 33))
70+
>deps.foo : Symbol(foo, Decl(contextSensitiveReturnTypeInference.ts, 11, 14))
71+
>deps : Symbol(deps, Decl(contextSensitiveReturnTypeInference.ts, 24, 3))
72+
>foo : Symbol(foo, Decl(contextSensitiveReturnTypeInference.ts, 11, 14))
73+
74+
fn2: data.bar
75+
>fn2 : Symbol(fn2, Decl(contextSensitiveReturnTypeInference.ts, 25, 40))
76+
>data.bar : Symbol(IData.bar, Decl(contextSensitiveReturnTypeInference.ts, 2, 17))
77+
>data : Symbol(data, Decl(contextSensitiveReturnTypeInference.ts, 24, 21))
78+
>bar : Symbol(IData.bar, Decl(contextSensitiveReturnTypeInference.ts, 2, 17))
79+
80+
}),
81+
DEPS
82+
>DEPS : Symbol(DEPS, Decl(contextSensitiveReturnTypeInference.ts, 11, 5))
83+
84+
);
85+
86+
test(
87+
>test : Symbol(test, Decl(contextSensitiveReturnTypeInference.ts, 4, 1))
88+
89+
(deps, data) => ({
90+
>deps : Symbol(deps, Decl(contextSensitiveReturnTypeInference.ts, 32, 3))
91+
>data : Symbol(data, Decl(contextSensitiveReturnTypeInference.ts, 32, 8))
92+
93+
fn1: () => deps.foo,
94+
>fn1 : Symbol(fn1, Decl(contextSensitiveReturnTypeInference.ts, 32, 20))
95+
>deps.foo : Symbol(foo, Decl(contextSensitiveReturnTypeInference.ts, 11, 14))
96+
>deps : Symbol(deps, Decl(contextSensitiveReturnTypeInference.ts, 32, 3))
97+
>foo : Symbol(foo, Decl(contextSensitiveReturnTypeInference.ts, 11, 14))
98+
99+
fn2: data.bar
100+
>fn2 : Symbol(fn2, Decl(contextSensitiveReturnTypeInference.ts, 33, 24))
101+
>data.bar : Symbol(IData.bar, Decl(contextSensitiveReturnTypeInference.ts, 2, 17))
102+
>data : Symbol(data, Decl(contextSensitiveReturnTypeInference.ts, 32, 8))
103+
>bar : Symbol(IData.bar, Decl(contextSensitiveReturnTypeInference.ts, 2, 17))
104+
105+
}),
106+
DEPS
107+
>DEPS : Symbol(DEPS, Decl(contextSensitiveReturnTypeInference.ts, 11, 5))
108+
109+
);
110+
111+
test(
112+
>test : Symbol(test, Decl(contextSensitiveReturnTypeInference.ts, 4, 1))
113+
114+
(deps, data) => {
115+
>deps : Symbol(deps, Decl(contextSensitiveReturnTypeInference.ts, 40, 3))
116+
>data : Symbol(data, Decl(contextSensitiveReturnTypeInference.ts, 40, 8))
117+
118+
return {
119+
fn1() { return deps.foo },
120+
>fn1 : Symbol(fn1, Decl(contextSensitiveReturnTypeInference.ts, 41, 12))
121+
>deps.foo : Symbol(foo, Decl(contextSensitiveReturnTypeInference.ts, 11, 14))
122+
>deps : Symbol(deps, Decl(contextSensitiveReturnTypeInference.ts, 40, 3))
123+
>foo : Symbol(foo, Decl(contextSensitiveReturnTypeInference.ts, 11, 14))
124+
125+
fn2: data.bar
126+
>fn2 : Symbol(fn2, Decl(contextSensitiveReturnTypeInference.ts, 42, 32))
127+
>data.bar : Symbol(IData.bar, Decl(contextSensitiveReturnTypeInference.ts, 2, 17))
128+
>data : Symbol(data, Decl(contextSensitiveReturnTypeInference.ts, 40, 8))
129+
>bar : Symbol(IData.bar, Decl(contextSensitiveReturnTypeInference.ts, 2, 17))
130+
}
131+
},
132+
DEPS
133+
>DEPS : Symbol(DEPS, Decl(contextSensitiveReturnTypeInference.ts, 11, 5))
134+
135+
);
136+
137+
test(
138+
>test : Symbol(test, Decl(contextSensitiveReturnTypeInference.ts, 4, 1))
139+
140+
(deps) => ({
141+
>deps : Symbol(deps, Decl(contextSensitiveReturnTypeInference.ts, 50, 3))
142+
143+
fn1() { return deps.foo },
144+
>fn1 : Symbol(fn1, Decl(contextSensitiveReturnTypeInference.ts, 50, 14))
145+
>deps.foo : Symbol(foo, Decl(contextSensitiveReturnTypeInference.ts, 11, 14))
146+
>deps : Symbol(deps, Decl(contextSensitiveReturnTypeInference.ts, 50, 3))
147+
>foo : Symbol(foo, Decl(contextSensitiveReturnTypeInference.ts, 11, 14))
148+
149+
fn2: 1
150+
>fn2 : Symbol(fn2, Decl(contextSensitiveReturnTypeInference.ts, 51, 30))
151+
152+
}),
153+
DEPS
154+
>DEPS : Symbol(DEPS, Decl(contextSensitiveReturnTypeInference.ts, 11, 5))
155+
156+
);
157+

0 commit comments

Comments
 (0)