@@ -922,6 +922,7 @@ namespace ts {
922922 if (!errorLocation ||
923923 !checkAndReportErrorForMissingPrefix(errorLocation, name, nameArg) &&
924924 !checkAndReportErrorForExtendingInterface(errorLocation) &&
925+ !checkAndReportErrorForUsingTypeAsNamespace(errorLocation, name, meaning) &&
925926 !checkAndReportErrorForUsingTypeAsValue(errorLocation, name, meaning)) {
926927 error(errorLocation, nameNotFoundMessage, typeof nameArg === "string" ? nameArg : declarationNameToString(nameArg));
927928 }
@@ -1032,6 +1033,18 @@ namespace ts {
10321033 }
10331034 }
10341035
1036+ function checkAndReportErrorForUsingTypeAsNamespace(errorLocation: Node, name: string, meaning: SymbolFlags): boolean {
1037+ if (meaning === SymbolFlags.Namespace) {
1038+ const symbol = resolveSymbol(resolveName(errorLocation, name, SymbolFlags.Type & ~SymbolFlags.Value, /*nameNotFoundMessage*/undefined, /*nameArg*/ undefined));
1039+ if (symbol) {
1040+ error(errorLocation, Diagnostics._0_only_refers_to_a_type_but_is_being_used_as_a_namespace_here, name);
1041+ return true;
1042+ }
1043+ }
1044+
1045+ return false;
1046+ }
1047+
10351048 function checkAndReportErrorForUsingTypeAsValue(errorLocation: Node, name: string, meaning: SymbolFlags): boolean {
10361049 if (meaning & (SymbolFlags.Value & ~SymbolFlags.NamespaceModule)) {
10371050 const symbol = resolveSymbol(resolveName(errorLocation, name, SymbolFlags.Type & ~SymbolFlags.Value, /*nameNotFoundMessage*/undefined, /*nameArg*/ undefined));
@@ -8975,7 +8988,7 @@ namespace ts {
89758988
89768989 function getTypeWithDefault(type: Type, defaultExpression: Expression) {
89778990 if (defaultExpression) {
8978- const defaultType = checkExpression (defaultExpression);
8991+ const defaultType = getTypeOfExpression (defaultExpression);
89798992 return getUnionType([getTypeWithFacts(type, TypeFacts.NEUndefined), defaultType]);
89808993 }
89818994 return type;
@@ -9002,7 +9015,7 @@ namespace ts {
90029015 function getAssignedTypeOfBinaryExpression(node: BinaryExpression): Type {
90039016 return node.parent.kind === SyntaxKind.ArrayLiteralExpression || node.parent.kind === SyntaxKind.PropertyAssignment ?
90049017 getTypeWithDefault(getAssignedType(node), node.right) :
9005- checkExpression (node.right);
9018+ getTypeOfExpression (node.right);
90069019 }
90079020
90089021 function getAssignedTypeOfArrayLiteralElement(node: ArrayLiteralExpression, element: Expression): Type {
@@ -9060,7 +9073,7 @@ namespace ts {
90609073 // from its initializer, we'll already have cached the type. Otherwise we compute it now
90619074 // without caching such that transient types are reflected.
90629075 const links = getNodeLinks(node);
9063- return links.resolvedType || checkExpression (node);
9076+ return links.resolvedType || getTypeOfExpression (node);
90649077 }
90659078
90669079 function getInitialTypeOfVariableDeclaration(node: VariableDeclaration) {
@@ -9120,7 +9133,7 @@ namespace ts {
91209133
91219134 function getTypeOfSwitchClause(clause: CaseClause | DefaultClause) {
91229135 if (clause.kind === SyntaxKind.CaseClause) {
9123- const caseType = getRegularTypeOfLiteralType(checkExpression ((<CaseClause>clause).expression));
9136+ const caseType = getRegularTypeOfLiteralType(getTypeOfExpression ((<CaseClause>clause).expression));
91249137 return isUnitType(caseType) ? caseType : undefined;
91259138 }
91269139 return neverType;
@@ -9225,7 +9238,7 @@ namespace ts {
92259238 // we defer subtype reduction until the evolving array type is finalized into a manifest
92269239 // array type.
92279240 function addEvolvingArrayElementType(evolvingArrayType: EvolvingArrayType, node: Expression): EvolvingArrayType {
9228- const elementType = getBaseTypeOfLiteralType(checkExpression (node));
9241+ const elementType = getBaseTypeOfLiteralType(getTypeOfExpression (node));
92299242 return isTypeSubsetOf(elementType, evolvingArrayType.elementType) ? evolvingArrayType : getEvolvingArrayType(getUnionType([evolvingArrayType.elementType, elementType]));
92309243 }
92319244
@@ -9286,7 +9299,7 @@ namespace ts {
92869299 (<BinaryExpression>parent.parent).operatorToken.kind === SyntaxKind.EqualsToken &&
92879300 (<BinaryExpression>parent.parent).left === parent &&
92889301 !isAssignmentTarget(parent.parent) &&
9289- isTypeAnyOrAllConstituentTypesHaveKind(checkExpression ((<ElementAccessExpression>parent).argumentExpression), TypeFlags.NumberLike | TypeFlags.Undefined);
9302+ isTypeAnyOrAllConstituentTypesHaveKind(getTypeOfExpression ((<ElementAccessExpression>parent).argumentExpression), TypeFlags.NumberLike | TypeFlags.Undefined);
92909303 return isLengthPushOrUnshift || isElementAssignment;
92919304 }
92929305
@@ -9448,7 +9461,7 @@ namespace ts {
94489461 }
94499462 }
94509463 else {
9451- const indexType = checkExpression ((<ElementAccessExpression>(<BinaryExpression>node).left).argumentExpression);
9464+ const indexType = getTypeOfExpression ((<ElementAccessExpression>(<BinaryExpression>node).left).argumentExpression);
94529465 if (isTypeAnyOrAllConstituentTypesHaveKind(indexType, TypeFlags.NumberLike | TypeFlags.Undefined)) {
94539466 evolvedType = addEvolvingArrayElementType(evolvedType, (<BinaryExpression>node).right);
94549467 }
@@ -9673,7 +9686,7 @@ namespace ts {
96739686 if (operator === SyntaxKind.ExclamationEqualsToken || operator === SyntaxKind.ExclamationEqualsEqualsToken) {
96749687 assumeTrue = !assumeTrue;
96759688 }
9676- const valueType = checkExpression (value);
9689+ const valueType = getTypeOfExpression (value);
96779690 if (valueType.flags & TypeFlags.Nullable) {
96789691 if (!strictNullChecks) {
96799692 return type;
@@ -9760,7 +9773,7 @@ namespace ts {
97609773 }
97619774
97629775 // Check that right operand is a function type with a prototype property
9763- const rightType = checkExpression (expr.right);
9776+ const rightType = getTypeOfExpression (expr.right);
97649777 if (!isTypeSubtypeOf(rightType, globalFunctionType)) {
97659778 return type;
97669779 }
@@ -9901,7 +9914,7 @@ namespace ts {
99019914 location = location.parent;
99029915 }
99039916 if (isPartOfExpression(location) && !isAssignmentTarget(location)) {
9904- const type = checkExpression (<Expression>location);
9917+ const type = getTypeOfExpression (<Expression>location);
99059918 if (getExportSymbolOfValueSymbolIfExported(getNodeLinks(location).resolvedSymbol) === symbol) {
99069919 return type;
99079920 }
@@ -10769,15 +10782,15 @@ namespace ts {
1076910782
1077010783 // In an assignment expression, the right operand is contextually typed by the type of the left operand.
1077110784 if (node === binaryExpression.right) {
10772- return checkExpression (binaryExpression.left);
10785+ return getTypeOfExpression (binaryExpression.left);
1077310786 }
1077410787 }
1077510788 else if (operator === SyntaxKind.BarBarToken) {
1077610789 // When an || expression has a contextual type, the operands are contextually typed by that type. When an ||
1077710790 // expression has no contextual type, the right operand is contextually typed by the type of the left operand.
1077810791 let type = getContextualType(binaryExpression);
1077910792 if (!type && node === binaryExpression.right) {
10780- type = checkExpression (binaryExpression.left);
10793+ type = getTypeOfExpression (binaryExpression.left);
1078110794 }
1078210795 return type;
1078310796 }
@@ -12148,7 +12161,7 @@ namespace ts {
1214812161 if (node.kind === SyntaxKind.ForInStatement &&
1214912162 child === (<ForInStatement>node).statement &&
1215012163 getForInVariableSymbol(<ForInStatement>node) === symbol &&
12151- hasNumericPropertyNames(checkExpression ((<ForInStatement>node).expression))) {
12164+ hasNumericPropertyNames(getTypeOfExpression ((<ForInStatement>node).expression))) {
1215212165 return true;
1215312166 }
1215412167 child = node;
@@ -13784,7 +13797,7 @@ namespace ts {
1378413797 if (!node.possiblyExhaustive) {
1378513798 return false;
1378613799 }
13787- const type = checkExpression (node.expression);
13800+ const type = getTypeOfExpression (node.expression);
1378813801 if (!isLiteralType(type)) {
1378913802 return false;
1379013803 }
@@ -14876,6 +14889,24 @@ namespace ts {
1487614889 return type;
1487714890 }
1487814891
14892+ // Returns the type of an expression. Unlike checkExpression, this function is simply concerned
14893+ // with computing the type and may not fully check all contained sub-expressions for errors.
14894+ function getTypeOfExpression(node: Expression) {
14895+ // Optimize for the common case of a call to a function with a single non-generic call
14896+ // signature where we can just fetch the return type without checking the arguments.
14897+ if (node.kind === SyntaxKind.CallExpression && (<CallExpression>node).expression.kind !== SyntaxKind.SuperKeyword) {
14898+ const funcType = checkNonNullExpression((<CallExpression>node).expression);
14899+ const signature = getSingleCallSignature(funcType);
14900+ if (signature && !signature.typeParameters) {
14901+ return getReturnTypeOfSignature(signature);
14902+ }
14903+ }
14904+ // Otherwise simply call checkExpression. Ideally, the entire family of checkXXX functions
14905+ // should have a parameter that indicates whether full error checking is required such that
14906+ // we can perform the optimizations locally.
14907+ return checkExpression(node);
14908+ }
14909+
1487914910 // Checks an expression and returns its type. The contextualMapper parameter serves two purposes: When
1488014911 // contextualMapper is not undefined and not equal to the identityMapper function object it indicates that the
1488114912 // expression is being inferentially typed (section 4.15.2 in spec) and provides the type mapper to use in
@@ -18258,7 +18289,7 @@ namespace ts {
1825818289 }
1825918290 }
1826018291
18261- enumType = checkExpression (expression);
18292+ enumType = getTypeOfExpression (expression);
1826218293 // allow references to constant members of other enums
1826318294 if (!(enumType.symbol && (enumType.symbol.flags & SymbolFlags.Enum))) {
1826418295 return undefined;
@@ -19428,7 +19459,7 @@ namespace ts {
1942819459 // fallthrough
1942919460
1943019461 case SyntaxKind.SuperKeyword:
19431- const type = isPartOfExpression(node) ? checkExpression (<Expression>node) : getTypeFromTypeNode(<TypeNode>node);
19462+ const type = isPartOfExpression(node) ? getTypeOfExpression (<Expression>node) : getTypeFromTypeNode(<TypeNode>node);
1943219463 return type.symbol;
1943319464
1943419465 case SyntaxKind.ThisType:
@@ -19458,7 +19489,7 @@ namespace ts {
1945819489 case SyntaxKind.NumericLiteral:
1945919490 // index access
1946019491 if (node.parent.kind === SyntaxKind.ElementAccessExpression && (<ElementAccessExpression>node.parent).argumentExpression === node) {
19461- const objectType = checkExpression ((<ElementAccessExpression>node.parent).expression);
19492+ const objectType = getTypeOfExpression ((<ElementAccessExpression>node.parent).expression);
1946219493 if (objectType === unknownType) return undefined;
1946319494 const apparentType = getApparentType(objectType);
1946419495 if (apparentType === unknownType) return undefined;
@@ -19497,7 +19528,7 @@ namespace ts {
1949719528 }
1949819529
1949919530 if (isPartOfExpression(node)) {
19500- return getTypeOfExpression (<Expression>node);
19531+ return getRegularTypeOfExpression (<Expression>node);
1950119532 }
1950219533
1950319534 if (isExpressionWithTypeArgumentsInClassExtendsClause(node)) {
@@ -19559,7 +19590,7 @@ namespace ts {
1955919590 // If this is from "for" initializer
1956019591 // for ({a } = elems[0];.....) { }
1956119592 if (expr.parent.kind === SyntaxKind.BinaryExpression) {
19562- const iteratedType = checkExpression ((<BinaryExpression>expr.parent).right);
19593+ const iteratedType = getTypeOfExpression ((<BinaryExpression>expr.parent).right);
1956319594 return checkDestructuringAssignment(expr, iteratedType || unknownType);
1956419595 }
1956519596 // If this is from nested object binding pattern
@@ -19589,11 +19620,11 @@ namespace ts {
1958919620 return typeOfObjectLiteral && getPropertyOfType(typeOfObjectLiteral, location.text);
1959019621 }
1959119622
19592- function getTypeOfExpression (expr: Expression): Type {
19623+ function getRegularTypeOfExpression (expr: Expression): Type {
1959319624 if (isRightSideOfQualifiedNameOrPropertyAccess(expr)) {
1959419625 expr = <Expression>expr.parent;
1959519626 }
19596- return getRegularTypeOfLiteralType(checkExpression (expr));
19627+ return getRegularTypeOfLiteralType(getTypeOfExpression (expr));
1959719628 }
1959819629
1959919630 /**
@@ -20020,7 +20051,7 @@ namespace ts {
2002020051 }
2002120052
2002220053 function writeTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: TypeFormatFlags, writer: SymbolWriter) {
20023- const type = getWidenedType(getTypeOfExpression (expr));
20054+ const type = getWidenedType(getRegularTypeOfExpression (expr));
2002420055 getSymbolDisplayBuilder().buildTypeDisplay(type, writer, enclosingDeclaration, flags);
2002520056 }
2002620057
0 commit comments