Skip to content

Commit 4b9b90a

Browse files
committed
Perform return type widening checks after union type is formed
1 parent b10f79b commit 4b9b90a

File tree

1 file changed

+8
-11
lines changed

1 file changed

+8
-11
lines changed

src/compiler/checker.ts

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12419,11 +12419,6 @@ namespace ts {
1241912419
return promiseType;
1242012420
}
1242112421

12422-
function checkReturnExpression(node: Expression, contextualMapper?: TypeMapper): Type {
12423-
const type = checkExpressionCached(node, contextualMapper);
12424-
return isUnitType(type) && !hasLiteralContextualType(node) ? getBaseTypeOfLiteralType(type) : type;
12425-
}
12426-
1242712422
function getReturnTypeFromBody(func: FunctionLikeDeclaration, contextualMapper?: TypeMapper): Type {
1242812423
const contextualSignature = getContextualSignatureForFunctionLikeDeclaration(func);
1242912424
if (!func.body) {
@@ -12433,7 +12428,7 @@ namespace ts {
1243312428
const isAsync = isAsyncFunctionLike(func);
1243412429
let type: Type;
1243512430
if (func.body.kind !== SyntaxKind.Block) {
12436-
type = checkReturnExpression(<Expression>func.body, contextualMapper);
12431+
type = checkExpressionCached(<Expression>func.body, contextualMapper);
1243712432
if (isAsync) {
1243812433
// From within an async function you can return either a non-promise value or a promise. Any
1243912434
// Promise/A+ compatible implementation will always assimilate any foreign promise, so the
@@ -12477,6 +12472,9 @@ namespace ts {
1247712472
if (!contextualSignature) {
1247812473
reportErrorsFromWidening(func, type);
1247912474
}
12475+
if (isUnitType(type) && !(contextualSignature && isLiteralContextualType(getReturnTypeOfSignature(contextualSignature)))) {
12476+
type = getBaseTypeOfLiteralType(type);
12477+
}
1248012478

1248112479
const widenedType = getWidenedType(type);
1248212480
// From within an async function you can return either a non-promise value or a promise. Any
@@ -12491,7 +12489,7 @@ namespace ts {
1249112489
forEachYieldExpression(<Block>func.body, yieldExpression => {
1249212490
const expr = yieldExpression.expression;
1249312491
if (expr) {
12494-
let type = checkReturnExpression(expr, contextualMapper);
12492+
let type = checkExpressionCached(expr, contextualMapper);
1249512493

1249612494
if (yieldExpression.asteriskToken) {
1249712495
// A yield* expression effectively yields everything that its operand yields
@@ -12541,7 +12539,7 @@ namespace ts {
1254112539
forEachReturnStatement(<Block>func.body, returnStatement => {
1254212540
const expr = returnStatement.expression;
1254312541
if (expr) {
12544-
let type = checkReturnExpression(expr, contextualMapper);
12542+
let type = checkExpressionCached(expr, contextualMapper);
1254512543
if (isAsync) {
1254612544
// From within an async function you can return either a non-promise value or a promise. Any
1254712545
// Promise/A+ compatible implementation will always assimilate any foreign promise, so the
@@ -13455,8 +13453,7 @@ namespace ts {
1345513453
return links.resolvedType;
1345613454
}
1345713455

13458-
function hasLiteralContextualType(node: Expression) {
13459-
let contextualType = getContextualType(node);
13456+
function isLiteralContextualType(contextualType: Type) {
1346013457
if (contextualType) {
1346113458
if (contextualType.flags & TypeFlags.TypeParameter) {
1346213459
const apparentType = getApparentTypeOfTypeParameter(<TypeParameter>contextualType);
@@ -13475,7 +13472,7 @@ namespace ts {
1347513472

1347613473
function checkExpressionForMutableLocation(node: Expression, contextualMapper?: TypeMapper): Type {
1347713474
const type = checkExpression(node, contextualMapper);
13478-
return hasLiteralContextualType(node) ? type : getBaseTypeOfLiteralType(type);
13475+
return isLiteralContextualType(getContextualType(node)) ? type : getBaseTypeOfLiteralType(type);
1347913476
}
1348013477

1348113478
function checkPropertyAssignment(node: PropertyAssignment, contextualMapper?: TypeMapper): Type {

0 commit comments

Comments
 (0)