Skip to content

Commit 3bee8eb

Browse files
committed
Allow implicit return with explicit undefined return type
1 parent 43cc362 commit 3bee8eb

7 files changed

+58
-29
lines changed

src/compiler/checker.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35469,8 +35469,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3546935469
const functionFlags = getFunctionFlags(func);
3547035470
const type = returnType && unwrapReturnType(returnType, functionFlags);
3547135471

35472-
// Functions with with an explicitly specified 'void' or 'any' return type don't need any return expressions.
35473-
if (type && maybeTypeOfKind(type, TypeFlags.Any | TypeFlags.Void)) {
35472+
// Functions with an explicitly specified 'undefined, 'void' or 'any' return type don't need any return expressions.
35473+
if (type && maybeTypeOfKind(type, TypeFlags.Undefined | TypeFlags.Void | TypeFlags.Any)) {
3547435474
return;
3547535475
}
3547635476

tests/baselines/reference/functionsMissingReturnStatementsAndExpressions.errors.txt

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
tests/cases/compiler/functionsMissingReturnStatementsAndExpressions.ts(1,16): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value.
22
tests/cases/compiler/functionsMissingReturnStatementsAndExpressions.ts(99,17): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value.
3-
tests/cases/compiler/functionsMissingReturnStatementsAndExpressions.ts(104,16): error TS2378: A 'get' accessor must return a value.
4-
tests/cases/compiler/functionsMissingReturnStatementsAndExpressions.ts(126,15): error TS18050: The value 'undefined' cannot be used here.
5-
tests/cases/compiler/functionsMissingReturnStatementsAndExpressions.ts(127,5): error TS1003: Identifier expected.
3+
tests/cases/compiler/functionsMissingReturnStatementsAndExpressions.ts(108,16): error TS2378: A 'get' accessor must return a value.
4+
tests/cases/compiler/functionsMissingReturnStatementsAndExpressions.ts(130,15): error TS18050: The value 'undefined' cannot be used here.
5+
tests/cases/compiler/functionsMissingReturnStatementsAndExpressions.ts(131,5): error TS1003: Identifier expected.
66

77

88
==== tests/cases/compiler/functionsMissingReturnStatementsAndExpressions.ts (5 errors) ====
@@ -40,12 +40,12 @@ tests/cases/compiler/functionsMissingReturnStatementsAndExpressions.ts(127,5): e
4040
return null;
4141
}
4242

43-
function f8(): void {
43+
function f8(): any {
4444
// Fine since are typed any.
4545
return;
4646
}
4747

48-
function f9(): void {
48+
function f9(): any {
4949
// Fine since we are typed any and return undefined
5050
return undefined;
5151
}
@@ -112,6 +112,10 @@ tests/cases/compiler/functionsMissingReturnStatementsAndExpressions.ts(127,5): e
112112
// Not okay; union does not contain void or any
113113
}
114114

115+
function f22(): undefined {
116+
// Okay; implicitly returns undefined
117+
}
118+
115119
class C {
116120
public get m1() {
117121
~~
@@ -143,4 +147,5 @@ tests/cases/compiler/functionsMissingReturnStatementsAndExpressions.ts(127,5): e
143147
}
144148
~
145149
!!! error TS1003: Identifier expected.
146-
}
150+
}
151+

tests/baselines/reference/functionsMissingReturnStatementsAndExpressions.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,12 @@ function f7(): void {
3131
return null;
3232
}
3333

34-
function f8(): void {
34+
function f8(): any {
3535
// Fine since are typed any.
3636
return;
3737
}
3838

39-
function f9(): void {
39+
function f9(): any {
4040
// Fine since we are typed any and return undefined
4141
return undefined;
4242
}
@@ -101,6 +101,10 @@ function f21(): number | string {
101101
// Not okay; union does not contain void or any
102102
}
103103

104+
function f22(): undefined {
105+
// Okay; implicitly returns undefined
106+
}
107+
104108
class C {
105109
public get m1() {
106110
// Errors; get accessors must return a value.
@@ -126,7 +130,8 @@ class C {
126130
throw null;
127131
throw undefined.
128132
}
129-
}
133+
}
134+
130135

131136
//// [functionsMissingReturnStatementsAndExpressions.js]
132137
function f1() {
@@ -209,6 +214,9 @@ function f20() {
209214
function f21() {
210215
// Not okay; union does not contain void or any
211216
}
217+
function f22() {
218+
// Okay; implicitly returns undefined
219+
}
212220
var C = /** @class */ (function () {
213221
function C() {
214222
}

tests/baselines/reference/functionsMissingReturnStatementsAndExpressions.symbols

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,14 @@ function f7(): void {
4646
return null;
4747
}
4848

49-
function f8(): void {
49+
function f8(): any {
5050
>f8 : Symbol(f8, Decl(functionsMissingReturnStatementsAndExpressions.ts, 30, 1))
5151

5252
// Fine since are typed any.
5353
return;
5454
}
5555

56-
function f9(): void {
56+
function f9(): any {
5757
>f9 : Symbol(f9, Decl(functionsMissingReturnStatementsAndExpressions.ts, 35, 1))
5858

5959
// Fine since we are typed any and return undefined
@@ -152,37 +152,43 @@ function f21(): number | string {
152152
// Not okay; union does not contain void or any
153153
}
154154

155+
function f22(): undefined {
156+
>f22 : Symbol(f22, Decl(functionsMissingReturnStatementsAndExpressions.ts, 100, 1))
157+
158+
// Okay; implicitly returns undefined
159+
}
160+
155161
class C {
156-
>C : Symbol(C, Decl(functionsMissingReturnStatementsAndExpressions.ts, 100, 1))
162+
>C : Symbol(C, Decl(functionsMissingReturnStatementsAndExpressions.ts, 104, 1))
157163

158164
public get m1() {
159-
>m1 : Symbol(C.m1, Decl(functionsMissingReturnStatementsAndExpressions.ts, 102, 9))
165+
>m1 : Symbol(C.m1, Decl(functionsMissingReturnStatementsAndExpressions.ts, 106, 9))
160166

161167
// Errors; get accessors must return a value.
162168
}
163169

164170
public get m2() {
165-
>m2 : Symbol(C.m2, Decl(functionsMissingReturnStatementsAndExpressions.ts, 105, 5))
171+
>m2 : Symbol(C.m2, Decl(functionsMissingReturnStatementsAndExpressions.ts, 109, 5))
166172

167173
// Permissible; returns undefined.
168174
return;
169175
}
170176

171177
public get m3() {
172-
>m3 : Symbol(C.m3, Decl(functionsMissingReturnStatementsAndExpressions.ts, 110, 5))
178+
>m3 : Symbol(C.m3, Decl(functionsMissingReturnStatementsAndExpressions.ts, 114, 5))
173179

174180
return "Okay, because this is a return expression.";
175181
}
176182

177183
public get m4() {
178-
>m4 : Symbol(C.m4, Decl(functionsMissingReturnStatementsAndExpressions.ts, 114, 5))
184+
>m4 : Symbol(C.m4, Decl(functionsMissingReturnStatementsAndExpressions.ts, 118, 5))
179185

180186
// Fine since this consists of a single throw statement.
181187
throw null;
182188
}
183189

184190
public get m5() {
185-
>m5 : Symbol(C.m5, Decl(functionsMissingReturnStatementsAndExpressions.ts, 119, 5))
191+
>m5 : Symbol(C.m5, Decl(functionsMissingReturnStatementsAndExpressions.ts, 123, 5))
186192

187193
// Not fine, since we can *only* consist of a single throw statement
188194
// if no return statements are present but we are a get accessor.
@@ -191,3 +197,4 @@ class C {
191197
>undefined : Symbol(undefined)
192198
}
193199
}
200+

tests/baselines/reference/functionsMissingReturnStatementsAndExpressions.types

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,15 @@ function f7(): void {
4848
>null : null
4949
}
5050

51-
function f8(): void {
52-
>f8 : () => void
51+
function f8(): any {
52+
>f8 : () => any
5353

5454
// Fine since are typed any.
5555
return;
5656
}
5757

58-
function f9(): void {
59-
>f9 : () => void
58+
function f9(): any {
59+
>f9 : () => any
6060

6161
// Fine since we are typed any and return undefined
6262
return undefined;
@@ -159,6 +159,12 @@ function f21(): number | string {
159159
// Not okay; union does not contain void or any
160160
}
161161

162+
function f22(): undefined {
163+
>f22 : () => undefined
164+
165+
// Okay; implicitly returns undefined
166+
}
167+
162168
class C {
163169
>C : C
164170

@@ -204,3 +210,4 @@ class C {
204210
}
205211
> : any
206212
}
213+

tests/cases/compiler/functionsMissingReturnStatementsAndExpressions.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,12 @@ function f7(): void {
3434
return null;
3535
}
3636

37-
function f8(): void {
37+
function f8(): any {
3838
// Fine since are typed any.
3939
return;
4040
}
4141

42-
function f9(): void {
42+
function f9(): any {
4343
// Fine since we are typed any and return undefined
4444
return undefined;
4545
}
@@ -104,6 +104,10 @@ function f21(): number | string {
104104
// Not okay; union does not contain void or any
105105
}
106106

107+
function f22(): undefined {
108+
// Okay; implicitly returns undefined
109+
}
110+
107111
class C {
108112
public get m1() {
109113
// Errors; get accessors must return a value.
@@ -129,4 +133,4 @@ class C {
129133
throw null;
130134
throw undefined.
131135
}
132-
}
136+
}

tests/cases/fourslash/codeFixCorrectReturnValue6.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,4 @@
44
//// undefined
55
//// }
66

7-
verify.codeFixAvailable([
8-
{ description: 'Add a return statement' },
9-
]);
7+
verify.not.codeFixAvailable();

0 commit comments

Comments
 (0)