From f1b84950eaae83ddcddac228186e3f4dfbbe0273 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 28 Dec 2015 15:10:01 -0500 Subject: [PATCH] Removed checks for specialized signature compatibility and always perform the same checking on specialized and non-specialized signatures. --- src/compiler/checker.ts | 70 +++-------------------------------------- 1 file changed, 4 insertions(+), 66 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5d57e9d2028..16e957f35b5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11273,8 +11273,6 @@ namespace ts { } } } - - checkSpecializedSignatureDeclaration(node); } function checkTypeForDuplicateIndexSignatures(node: Node) { @@ -11589,48 +11587,6 @@ namespace ts { return (node.flags & NodeFlags.Private) && isInAmbientContext(node); } - function checkSpecializedSignatureDeclaration(signatureDeclarationNode: SignatureDeclaration): void { - if (!produceDiagnostics) { - return; - } - const signature = getSignatureFromDeclaration(signatureDeclarationNode); - if (!signature.hasStringLiterals) { - return; - } - - // TypeScript 1.0 spec (April 2014): 3.7.2.2 - // Specialized signatures are not permitted in conjunction with a function body - if (nodeIsPresent((signatureDeclarationNode).body)) { - error(signatureDeclarationNode, Diagnostics.A_signature_with_an_implementation_cannot_use_a_string_literal_type); - return; - } - - // TypeScript 1.0 spec (April 2014): 3.7.2.4 - // Every specialized call or construct signature in an object type must be assignable - // to at least one non-specialized call or construct signature in the same object type - let signaturesToCheck: Signature[]; - // Unnamed (call\construct) signatures in interfaces are inherited and not shadowed so examining just node symbol won't give complete answer. - // Use declaring type to obtain full list of signatures. - if (!signatureDeclarationNode.name && signatureDeclarationNode.parent && signatureDeclarationNode.parent.kind === SyntaxKind.InterfaceDeclaration) { - Debug.assert(signatureDeclarationNode.kind === SyntaxKind.CallSignature || signatureDeclarationNode.kind === SyntaxKind.ConstructSignature); - const signatureKind = signatureDeclarationNode.kind === SyntaxKind.CallSignature ? SignatureKind.Call : SignatureKind.Construct; - const containingSymbol = getSymbolOfNode(signatureDeclarationNode.parent); - const containingType = getDeclaredTypeOfSymbol(containingSymbol); - signaturesToCheck = getSignaturesOfType(containingType, signatureKind); - } - else { - signaturesToCheck = getSignaturesOfSymbol(getSymbolOfNode(signatureDeclarationNode)); - } - - for (const otherSignature of signaturesToCheck) { - if (!otherSignature.hasStringLiterals && isSignatureAssignableTo(signature, otherSignature, /*ignoreReturnTypes*/ false)) { - return; - } - } - - error(signatureDeclarationNode, Diagnostics.Specialized_overload_signature_is_not_assignable_to_any_non_specialized_signature); - } - function getEffectiveDeclarationFlags(n: Node, flagsToCheck: NodeFlags): NodeFlags { let flags = getCombinedNodeFlags(n); @@ -11852,28 +11808,10 @@ namespace ts { if (bodyDeclaration) { const signatures = getSignaturesOfSymbol(symbol); const bodySignature = getSignatureFromDeclaration(bodyDeclaration); - // If the implementation signature has string literals, we will have reported an error in - // checkSpecializedSignatureDeclaration - if (!bodySignature.hasStringLiterals) { - // TypeScript 1.0 spec (April 2014): 6.1 - // If a function declaration includes overloads, the overloads determine the call - // signatures of the type given to the function object - // and the function implementation signature must be assignable to that type - // - // TypeScript 1.0 spec (April 2014): 3.8.4 - // Note that specialized call and construct signatures (section 3.7.2.4) are not significant when determining assignment compatibility - // Consider checking against specialized signatures too. Not doing so creates a type hole: - // - // function g(x: "hi", y: boolean); - // function g(x: string, y: {}); - // function g(x: string, y: string) { } - // - // The implementation is completely unrelated to the specialized signature, yet we do not check this. - for (const signature of signatures) { - if (!signature.hasStringLiterals && !isImplementationCompatibleWithOverload(bodySignature, signature)) { - error(signature.declaration, Diagnostics.Overload_signature_is_not_compatible_with_function_implementation); - break; - } + for (const signature of signatures) { + if (!isImplementationCompatibleWithOverload(bodySignature, signature)) { + error(signature.declaration, Diagnostics.Overload_signature_is_not_compatible_with_function_implementation); + break; } } }