diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1957ebf23bb..7835a5e3e72 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7996,7 +7996,7 @@ namespace ts { return unknownType; } - function getTypeFromThisTypeNode(node: TypeNode): Type { + function getTypeFromThisTypeNode(node: ThisExpression | ThisTypeNode): Type { const links = getNodeLinks(node); if (!links.resolvedType) { links.resolvedType = getThisType(node); @@ -8030,7 +8030,7 @@ namespace ts { return node.flags & NodeFlags.JavaScriptFile ? anyType : nonPrimitiveType; case SyntaxKind.ThisType: case SyntaxKind.ThisKeyword: - return getTypeFromThisTypeNode(node); + return getTypeFromThisTypeNode(node as ThisExpression | ThisTypeNode); case SyntaxKind.LiteralType: return getTypeFromLiteralTypeNode(node); case SyntaxKind.TypeReference: @@ -23065,14 +23065,16 @@ namespace ts { return sig.thisParameter; } } + if (isInExpressionContext(node)) { + return checkExpression(node as Expression).symbol; + } // falls through - case SyntaxKind.SuperKeyword: - const type = isPartOfExpression(node) ? getTypeOfExpression(node) : getTypeFromTypeNode(node); - return type.symbol; - case SyntaxKind.ThisType: - return getTypeFromTypeNode(node).symbol; + return getTypeFromThisTypeNode(node as ThisExpression | ThisTypeNode).symbol; + + case SyntaxKind.SuperKeyword: + return checkExpression(node as Expression).symbol; case SyntaxKind.ConstructorKeyword: // constructor keyword for an overload, should take us to the definition if it exist diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 64d5bcaac62..47cf2038f03 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1253,57 +1253,60 @@ namespace ts { case SyntaxKind.NumericLiteral: case SyntaxKind.StringLiteral: case SyntaxKind.ThisKeyword: - const parent = node.parent; - switch (parent.kind) { - case SyntaxKind.VariableDeclaration: - case SyntaxKind.Parameter: - case SyntaxKind.PropertyDeclaration: - case SyntaxKind.PropertySignature: - case SyntaxKind.EnumMember: - case SyntaxKind.PropertyAssignment: - case SyntaxKind.BindingElement: - return (parent).initializer === node; - case SyntaxKind.ExpressionStatement: - case SyntaxKind.IfStatement: - case SyntaxKind.DoStatement: - case SyntaxKind.WhileStatement: - case SyntaxKind.ReturnStatement: - case SyntaxKind.WithStatement: - case SyntaxKind.SwitchStatement: - case SyntaxKind.CaseClause: - case SyntaxKind.ThrowStatement: - return (parent).expression === node; - case SyntaxKind.ForStatement: - const forStatement = parent; - return (forStatement.initializer === node && forStatement.initializer.kind !== SyntaxKind.VariableDeclarationList) || - forStatement.condition === node || - forStatement.incrementor === node; - case SyntaxKind.ForInStatement: - case SyntaxKind.ForOfStatement: - const forInStatement = parent; - return (forInStatement.initializer === node && forInStatement.initializer.kind !== SyntaxKind.VariableDeclarationList) || - forInStatement.expression === node; - case SyntaxKind.TypeAssertionExpression: - case SyntaxKind.AsExpression: - return node === (parent).expression; - case SyntaxKind.TemplateSpan: - return node === (parent).expression; - case SyntaxKind.ComputedPropertyName: - return node === (parent).expression; - case SyntaxKind.Decorator: - case SyntaxKind.JsxExpression: - case SyntaxKind.JsxSpreadAttribute: - case SyntaxKind.SpreadAssignment: - return true; - case SyntaxKind.ExpressionWithTypeArguments: - return (parent).expression === node && isExpressionWithTypeArgumentsInClassExtendsClause(parent); - default: - if (isPartOfExpression(parent)) { - return true; - } - } + return isInExpressionContext(node); + default: + return false; + } + } + + export function isInExpressionContext(node: Node): boolean { + const parent = node.parent; + switch (parent.kind) { + case SyntaxKind.VariableDeclaration: + case SyntaxKind.Parameter: + case SyntaxKind.PropertyDeclaration: + case SyntaxKind.PropertySignature: + case SyntaxKind.EnumMember: + case SyntaxKind.PropertyAssignment: + case SyntaxKind.BindingElement: + return (parent).initializer === node; + case SyntaxKind.ExpressionStatement: + case SyntaxKind.IfStatement: + case SyntaxKind.DoStatement: + case SyntaxKind.WhileStatement: + case SyntaxKind.ReturnStatement: + case SyntaxKind.WithStatement: + case SyntaxKind.SwitchStatement: + case SyntaxKind.CaseClause: + case SyntaxKind.ThrowStatement: + return (parent).expression === node; + case SyntaxKind.ForStatement: + const forStatement = parent; + return (forStatement.initializer === node && forStatement.initializer.kind !== SyntaxKind.VariableDeclarationList) || + forStatement.condition === node || + forStatement.incrementor === node; + case SyntaxKind.ForInStatement: + case SyntaxKind.ForOfStatement: + const forInStatement = parent; + return (forInStatement.initializer === node && forInStatement.initializer.kind !== SyntaxKind.VariableDeclarationList) || + forInStatement.expression === node; + case SyntaxKind.TypeAssertionExpression: + case SyntaxKind.AsExpression: + return node === (parent).expression; + case SyntaxKind.TemplateSpan: + return node === (parent).expression; + case SyntaxKind.ComputedPropertyName: + return node === (parent).expression; + case SyntaxKind.Decorator: + case SyntaxKind.JsxExpression: + case SyntaxKind.JsxSpreadAttribute: + case SyntaxKind.SpreadAssignment: + return true; + case SyntaxKind.ExpressionWithTypeArguments: + return (parent).expression === node && isExpressionWithTypeArgumentsInClassExtendsClause(parent); + default: + return isPartOfExpression(parent); } - return false; } export function isExternalModuleImportEqualsDeclaration(node: Node) {