Skip to content

Commit f3a12d1

Browse files
committed
Check return types
1 parent 6fd5e1b commit f3a12d1

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

src/compiler/checker.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4937,6 +4937,10 @@ namespace ts {
49374937
return type.resolvedApparentType || (type.resolvedApparentType = getTypeWithThisArgument(type, type));
49384938
}
49394939

4940+
function getApparentTypeOfReturnType(type: ReturnType) {
4941+
return type.resolvedApparentType || (type.resolvedApparentType = getReturnType(getApparentType(type.type)));
4942+
}
4943+
49404944
/**
49414945
* For a type parameter, return the base constraint of the type parameter. For the string, number,
49424946
* boolean, and symbol primitive types, return the corresponding object types. Otherwise return the
@@ -4945,6 +4949,7 @@ namespace ts {
49454949
function getApparentType(type: Type): Type {
49464950
const t = type.flags & TypeFlags.TypeVariable ? getBaseConstraintOfType(<TypeVariable>type) || emptyObjectType : type;
49474951
return t.flags & TypeFlags.Intersection ? getApparentTypeOfIntersectionType(<IntersectionType>t) :
4952+
t.flags & TypeFlags.Return ? getApparentTypeOfReturnType(<ReturnType>t) :
49484953
t.flags & TypeFlags.StringLike ? globalStringType :
49494954
t.flags & TypeFlags.NumberLike ? globalNumberType :
49504955
t.flags & TypeFlags.BooleanLike ? globalBooleanType :
@@ -6188,6 +6193,29 @@ namespace ts {
61886193
return links.resolvedType;
61896194
}
61906195

6196+
function getTypeFromReturnOperatorNode(node: ReturnOperatorNode) {
6197+
const links = getNodeLinks(node);
6198+
if (!links.resolvedType) {
6199+
links.resolvedType = getReturnType(getTypeFromTypeNode(node.type));
6200+
}
6201+
return links.resolvedType;
6202+
}
6203+
6204+
function getReturnType(type: Type): Type {
6205+
if (maybeTypeOfKind(type, TypeFlags.TypeVariable)) {
6206+
return getReturnTypeForGenericType(type as TypeVariable | UnionOrIntersectionType);
6207+
}
6208+
return getUnionType(map(getSignaturesOfType(type, SignatureKind.Call), getReturnTypeOfSignature));
6209+
}
6210+
6211+
function getReturnTypeForGenericType(type: TypeVariable | UnionOrIntersectionType): Type {
6212+
if (!type.resolvedReturnType) {
6213+
type.resolvedReturnType = <ReturnType>createType(TypeFlags.Return);
6214+
type.resolvedReturnType.type = type;
6215+
}
6216+
return type.resolvedReturnType;
6217+
}
6218+
61916219
function createIndexedAccessType(objectType: Type, indexType: Type) {
61926220
const type = <IndexedAccessType>createType(TypeFlags.IndexedAccess);
61936221
type.objectType = objectType;
@@ -6595,7 +6623,9 @@ namespace ts {
65956623
case SyntaxKind.JSDocFunctionType:
65966624
return getTypeFromTypeLiteralOrFunctionOrConstructorTypeNode(node);
65976625
case SyntaxKind.TypeOperator:
6598-
return getTypeFromTypeOperatorNode(<TypeOperatorNode>node);
6626+
return getTypeFromTypeOperatorNode(node as TypeOperatorNode);
6627+
case SyntaxKind.ReturnOperator:
6628+
return getTypeFromReturnOperatorNode(node as ReturnOperatorNode);
65996629
case SyntaxKind.IndexedAccessType:
66006630
return getTypeFromIndexedAccessTypeNode(<IndexedAccessTypeNode>node);
66016631
case SyntaxKind.MappedType:
@@ -6962,6 +6992,9 @@ namespace ts {
69626992
if (type.flags & TypeFlags.Index) {
69636993
return getIndexType(instantiateType((<IndexType>type).type, mapper));
69646994
}
6995+
if (type.flags & TypeFlags.Return) {
6996+
return getReturnType(instantiateType((<ReturnType>type).type, mapper));
6997+
}
69656998
if (type.flags & TypeFlags.IndexedAccess) {
69666999
return getIndexedAccessType(instantiateType((<IndexedAccessType>type).objectType, mapper), instantiateType((<IndexedAccessType>type).indexType, mapper));
69677000
}

src/compiler/types.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2830,6 +2830,7 @@
28302830
/* @internal */
28312831
ContainsAnyFunctionType = 1 << 23, // Type is or contains object literal type
28322832
NonPrimitive = 1 << 24, // intrinsic object type
2833+
Return = 1 << 25, // Return type of callable (never for uncallable types)
28332834

28342835
/* @internal */
28352836
Nullable = Undefined | Null,
@@ -2970,6 +2971,8 @@
29702971
/* @internal */
29712972
resolvedIndexType: IndexType;
29722973
/* @internal */
2974+
resolvedReturnType: ReturnType;
2975+
/* @internal */
29732976
resolvedBaseConstraint: Type;
29742977
/* @internal */
29752978
couldContainTypeVariables: boolean;
@@ -3037,6 +3040,8 @@
30373040
resolvedBaseConstraint: Type;
30383041
/* @internal */
30393042
resolvedIndexType: IndexType;
3043+
/* @internal */
3044+
resolvedReturnType: ReturnType;
30403045
}
30413046

30423047
// Type parameters (TypeFlags.TypeParameter)
@@ -3063,6 +3068,13 @@
30633068
type: TypeVariable | UnionOrIntersectionType;
30643069
}
30653070

3071+
// return T types (TypeFlags.Return)
3072+
export interface ReturnType extends Type {
3073+
type: TypeVariable | UnionOrIntersectionType;
3074+
/* @internal */
3075+
resolvedApparentType: Type;
3076+
}
3077+
30663078
export const enum SignatureKind {
30673079
Call,
30683080
Construct,

0 commit comments

Comments
 (0)