diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index 8551652c176d5..346fddc303db1 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -153,6 +153,10 @@ namespace ts {
                 node = getParseTreeNode(node, isExpression);
                 return node ? getContextualType(node) : undefined;
             },
+            getContextualSignature: node => {
+                node = getParseTreeNode(node, isContextualSignatureNode);
+                return node ? getContextualSignature(node) : undefined;
+            },
             getFullyQualifiedName,
             getResolvedSignature: (node, candidatesOutArray?) => {
                 node = getParseTreeNode(node, isCallLikeExpression);
@@ -8244,14 +8248,13 @@ namespace ts {
 
         // Returns true if the given expression contains (at any level of nesting) a function or arrow expression
         // that is subject to contextual typing.
-        function isContextSensitive(node: Expression | MethodDeclaration | ObjectLiteralElementLike | JsxAttributeLike): boolean {
-            Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
+        function isContextSensitive(node: Expression | ObjectLiteralElementLike & { parent: ObjectLiteralExpression } | JsxAttributeLike): boolean {
             switch (node.kind) {
                 case SyntaxKind.FunctionExpression:
                 case SyntaxKind.ArrowFunction:
                     return isContextSensitiveFunctionLikeDeclaration(<FunctionExpression>node);
                 case SyntaxKind.ObjectLiteralExpression:
-                    return forEach((<ObjectLiteralExpression>node).properties, isContextSensitive);
+                    return forEach((<ObjectLiteralExpression>node).properties as Array<ObjectLiteralElementLike & { parent: ObjectLiteralExpression }>, isContextSensitive);
                 case SyntaxKind.ArrayLiteralExpression:
                     return forEach((<ArrayLiteralExpression>node).elements, isContextSensitive);
                 case SyntaxKind.ConditionalExpression:
@@ -8301,8 +8304,8 @@ namespace ts {
             return !(parameter && parameterIsThisKeyword(parameter));
         }
 
-        function isContextSensitiveFunctionOrObjectLiteralMethod(func: Node): func is FunctionExpression | ArrowFunction | MethodDeclaration {
-            return (isFunctionExpressionOrArrowFunction(func) || isObjectLiteralMethod(func)) && isContextSensitiveFunctionLikeDeclaration(func);
+        function isContextSensitiveFunctionOrObjectLiteralMethod(func: Node): func is ContextualSignatureNode {
+            return isContextualSignatureNode(func) && isContextSensitiveFunctionLikeDeclaration(func);
         }
 
         function getTypeWithoutSignatures(type: Type): Type {
@@ -13011,18 +13014,12 @@ namespace ts {
             return sourceLength < targetParameterCount;
         }
 
-        function isFunctionExpressionOrArrowFunction(node: Node): node is FunctionExpression | ArrowFunction {
-            return node.kind === SyntaxKind.FunctionExpression || node.kind === SyntaxKind.ArrowFunction;
-        }
-
         function getContextualSignatureForFunctionLikeDeclaration(node: FunctionLikeDeclaration): Signature {
             // Only function expressions, arrow functions, and object literal methods are contextually typed.
-            return isFunctionExpressionOrArrowFunction(node) || isObjectLiteralMethod(node)
-                ? getContextualSignature(<FunctionExpression>node)
-                : undefined;
+            return isContextualSignatureNode(node) ? getContextualSignature(node) : undefined;
         }
 
-        function getContextualTypeForFunctionLikeDeclaration(node: FunctionExpression | ArrowFunction | MethodDeclaration) {
+        function getContextualTypeForFunctionLikeDeclaration(node: ContextualSignatureNode): Type | undefined {
             return isObjectLiteralMethod(node) ?
                 getContextualTypeForObjectLiteralMethod(node) :
                 getApparentTypeOfContextualType(node);
@@ -13033,8 +13030,7 @@ namespace ts {
         // If the contextual type is a union type, get the signature from each type possible and if they are
         // all identical ignoring their return type, the result is same signature but with return type as
         // union type of return types from these signatures
-        function getContextualSignature(node: FunctionExpression | ArrowFunction | MethodDeclaration): Signature {
-            Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
+        function getContextualSignature(node: ContextualSignatureNode): Signature {
             const type = getContextualTypeForFunctionLikeDeclaration(node);
             if (!type) {
                 return undefined;
@@ -13257,14 +13253,14 @@ namespace ts {
                     isObjectLiteralMethod(memberDecl)) {
                     let type: Type;
                     if (memberDecl.kind === SyntaxKind.PropertyAssignment) {
-                        type = checkPropertyAssignment(<PropertyAssignment>memberDecl, checkMode);
+                        type = checkPropertyAssignment(memberDecl, checkMode);
                     }
                     else if (memberDecl.kind === SyntaxKind.MethodDeclaration) {
-                        type = checkObjectLiteralMethod(<MethodDeclaration>memberDecl, checkMode);
+                        type = checkObjectLiteralMethod(memberDecl, checkMode);
                     }
                     else {
                         Debug.assert(memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment);
-                        type = checkExpressionForMutableLocation((<ShorthandPropertyAssignment>memberDecl).name, checkMode);
+                        type = checkExpressionForMutableLocation(memberDecl.name, checkMode);
                     }
 
                     typeFlags |= type.flags;
@@ -13273,8 +13269,8 @@ namespace ts {
                         // If object literal is an assignment pattern and if the assignment pattern specifies a default value
                         // for the property, make the property optional.
                         const isOptional =
-                            (memberDecl.kind === SyntaxKind.PropertyAssignment && hasDefaultValue((<PropertyAssignment>memberDecl).initializer)) ||
-                            (memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment && (<ShorthandPropertyAssignment>memberDecl).objectAssignmentInitializer);
+                            (memberDecl.kind === SyntaxKind.PropertyAssignment && hasDefaultValue(memberDecl.initializer)) ||
+                            (memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment && memberDecl.objectAssignmentInitializer);
                         if (isOptional) {
                             prop.flags |= SymbolFlags.Optional;
                         }
@@ -16525,9 +16521,7 @@ namespace ts {
             }
         }
 
-        function checkFunctionExpressionOrObjectLiteralMethod(node: FunctionExpression | MethodDeclaration, checkMode?: CheckMode): Type {
-            Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
-
+        function checkFunctionExpressionOrObjectLiteralMethod(node: ContextualSignatureNode, checkMode?: CheckMode): Type {
             // Grammar checking
             const hasGrammarError = checkGrammarFunctionLikeDeclaration(node);
             if (!hasGrammarError && node.kind === SyntaxKind.FunctionExpression) {
@@ -16585,9 +16579,7 @@ namespace ts {
             return type;
         }
 
-        function checkFunctionExpressionOrObjectLiteralMethodDeferred(node: ArrowFunction | FunctionExpression | MethodDeclaration) {
-            Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
-
+        function checkFunctionExpressionOrObjectLiteralMethodDeferred(node: ContextualSignatureNode) {
             const functionFlags = getFunctionFlags(node);
             const returnOrPromisedType = node.type &&
                 ((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.Async ?
@@ -17521,7 +17513,7 @@ namespace ts {
             return checkExpressionForMutableLocation((<PropertyAssignment>node).initializer, checkMode);
         }
 
-        function checkObjectLiteralMethod(node: MethodDeclaration, checkMode?: CheckMode): Type {
+        function checkObjectLiteralMethod(node: MethodDeclaration & { parent: ObjectLiteralExpression }, checkMode?: CheckMode): Type {
             // Grammar checking
             checkGrammarMethod(node);
 
@@ -17664,7 +17656,7 @@ namespace ts {
                     return checkClassExpression(<ClassExpression>node);
                 case SyntaxKind.FunctionExpression:
                 case SyntaxKind.ArrowFunction:
-                    return checkFunctionExpressionOrObjectLiteralMethod(<FunctionExpression>node, checkMode);
+                    return checkFunctionExpressionOrObjectLiteralMethod(<FunctionExpression | ArrowFunction>node, checkMode);
                 case SyntaxKind.TypeOfExpression:
                     return checkTypeOfExpression(<TypeOfExpression>node);
                 case SyntaxKind.TypeAssertionExpression:
diff --git a/src/compiler/types.ts b/src/compiler/types.ts
index 98efa1f3e53b3..c5329ad7175d7 100644
--- a/src/compiler/types.ts
+++ b/src/compiler/types.ts
@@ -721,6 +721,9 @@ namespace ts {
         | AccessorDeclaration
         ;
 
+    /** Type of nodes that may have a contextual signature. */
+    export type ContextualSignatureNode = FunctionExpression | ArrowFunction | MethodDeclaration & { parent: ObjectLiteralExpression };
+
     export interface PropertyAssignment extends ObjectLiteralElement {
         kind: SyntaxKind.PropertyAssignment;
         name: PropertyName;
@@ -2545,6 +2548,7 @@ namespace ts {
         getAugmentedPropertiesOfType(type: Type): Symbol[];
         getRootSymbols(symbol: Symbol): Symbol[];
         getContextualType(node: Expression): Type | undefined;
+        getContextualSignature(node: ContextualSignatureNode): Signature | undefined;
         getResolvedSignature(node: CallLikeExpression, candidatesOutArray?: Signature[]): Signature | undefined;
         getSignatureFromDeclaration(declaration: SignatureDeclaration): Signature | undefined;
         isImplementationOfOverload(node: FunctionLikeDeclaration): boolean | undefined;
diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts
index a575024870775..368d57addf96b 100644
--- a/src/compiler/utilities.ts
+++ b/src/compiler/utilities.ts
@@ -934,7 +934,11 @@ namespace ts {
         return node && node.kind === SyntaxKind.Block && isFunctionLike(node.parent);
     }
 
-    export function isObjectLiteralMethod(node: Node): node is MethodDeclaration {
+    export function isContextualSignatureNode(node: Node): node is ContextualSignatureNode {
+        return node.kind === SyntaxKind.FunctionExpression || node.kind === SyntaxKind.ArrowFunction || isObjectLiteralMethod(node);
+    }
+
+    export function isObjectLiteralMethod(node: Node): node is MethodDeclaration & { parent: ObjectLiteralExpression } {
         return node && node.kind === SyntaxKind.MethodDeclaration && node.parent.kind === SyntaxKind.ObjectLiteralExpression;
     }