mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-16 15:51:35 -05:00
Unify untyped call checking between decorators and template tags.
This commit is contained in:
@@ -11943,18 +11943,12 @@ namespace ts {
|
||||
// Function interface, since they have none by default. This is a bit of a leap of faith
|
||||
// that the user will not add any.
|
||||
const callSignatures = getSignaturesOfType(apparentType, SignatureKind.Call);
|
||||
|
||||
const constructSignatures = getSignaturesOfType(apparentType, SignatureKind.Construct);
|
||||
// TS 1.0 spec: 4.12
|
||||
// If FuncExpr is of type Any, or of an object type that has no call or construct signatures
|
||||
// but is a subtype of the Function interface, the call is an untyped function call. In an
|
||||
// untyped function call no TypeArgs are permitted, Args can be any argument list, no contextual
|
||||
|
||||
// TS 1.0 Spec: 4.12
|
||||
// In an untyped function call no TypeArgs are permitted, Args can be any argument list, no contextual
|
||||
// types are provided for the argument expressions, and the result is always of type Any.
|
||||
// We exclude union types because we may have a union of function types that happen to have
|
||||
// no common signatures.
|
||||
if (isTypeAny(funcType) ||
|
||||
(isTypeAny(apparentType) && funcType.flags & TypeFlags.TypeParameter) ||
|
||||
(!callSignatures.length && !constructSignatures.length && !(funcType.flags & TypeFlags.Union) && isTypeAssignableTo(funcType, globalFunctionType))) {
|
||||
if (isUntypedFunctionCall(funcType, apparentType, callSignatures.length, constructSignatures.length)) {
|
||||
// The unknownType indicates that an error already occurred (and was reported). No
|
||||
// need to report another error in this case.
|
||||
if (funcType !== unknownType && node.typeArguments) {
|
||||
@@ -11977,6 +11971,29 @@ namespace ts {
|
||||
return resolveCall(node, callSignatures, candidatesOutArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* TS 1.0 spec: 4.12
|
||||
* If FuncExpr is of type Any, or of an object type that has no call or construct signatures
|
||||
* but is a subtype of the Function interface, the call is an untyped function call.
|
||||
*/
|
||||
function isUntypedFunctionCall(funcType: Type, apparentFuncType: Type, numCallSignatures: number, numConstructSignatures: number) {
|
||||
if (isTypeAny(funcType)) {
|
||||
return true;
|
||||
}
|
||||
if (isTypeAny(apparentFuncType) && funcType.flags & TypeFlags.TypeParameter) {
|
||||
return true;
|
||||
}
|
||||
if (!numCallSignatures && !numConstructSignatures) {
|
||||
// We exclude union types because we may have a union of function types that happen to have
|
||||
// no common signatures.
|
||||
if (funcType.flags & TypeFlags.Union) {
|
||||
return false;
|
||||
}
|
||||
return isTypeAssignableTo(funcType, globalFunctionType);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function resolveNewExpression(node: NewExpression, candidatesOutArray: Signature[]): Signature {
|
||||
if (node.arguments && languageVersion < ScriptTarget.ES5) {
|
||||
const spreadIndex = getSpreadArgumentIndex(node.arguments);
|
||||
@@ -12102,8 +12119,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
const callSignatures = getSignaturesOfType(apparentType, SignatureKind.Call);
|
||||
const constructSignatures = getSignaturesOfType(apparentType, SignatureKind.Construct);
|
||||
|
||||
if (isTypeAny(tagType) || (!callSignatures.length && !(tagType.flags & TypeFlags.Union) && isTypeAssignableTo(tagType, globalFunctionType))) {
|
||||
if (isUntypedFunctionCall(tagType, apparentType, callSignatures.length, constructSignatures.length)) {
|
||||
return resolveUntypedCall(node);
|
||||
}
|
||||
|
||||
@@ -12148,7 +12166,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
const callSignatures = getSignaturesOfType(apparentType, SignatureKind.Call);
|
||||
if (funcType === anyType || (!callSignatures.length && !(funcType.flags & TypeFlags.Union) && isTypeAssignableTo(funcType, globalFunctionType))) {
|
||||
const constructSignatures = getSignaturesOfType(apparentType, SignatureKind.Construct);
|
||||
if (isUntypedFunctionCall(funcType, apparentType, callSignatures.length, constructSignatures.length)) {
|
||||
return resolveUntypedCall(node);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user