Skip to content

Commit 7ecbfb2

Browse files
Unify untyped call checking between decorators and template tags.
1 parent d6ec5f2 commit 7ecbfb2

File tree

1 file changed

+31
-12
lines changed

1 file changed

+31
-12
lines changed

src/compiler/checker.ts

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11943,18 +11943,12 @@ namespace ts {
1194311943
// Function interface, since they have none by default. This is a bit of a leap of faith
1194411944
// that the user will not add any.
1194511945
const callSignatures = getSignaturesOfType(apparentType, SignatureKind.Call);
11946-
1194711946
const constructSignatures = getSignaturesOfType(apparentType, SignatureKind.Construct);
11948-
// TS 1.0 spec: 4.12
11949-
// If FuncExpr is of type Any, or of an object type that has no call or construct signatures
11950-
// but is a subtype of the Function interface, the call is an untyped function call. In an
11951-
// untyped function call no TypeArgs are permitted, Args can be any argument list, no contextual
11947+
11948+
// TS 1.0 Spec: 4.12
11949+
// In an untyped function call no TypeArgs are permitted, Args can be any argument list, no contextual
1195211950
// types are provided for the argument expressions, and the result is always of type Any.
11953-
// We exclude union types because we may have a union of function types that happen to have
11954-
// no common signatures.
11955-
if (isTypeAny(funcType) ||
11956-
(isTypeAny(apparentType) && funcType.flags & TypeFlags.TypeParameter) ||
11957-
(!callSignatures.length && !constructSignatures.length && !(funcType.flags & TypeFlags.Union) && isTypeAssignableTo(funcType, globalFunctionType))) {
11951+
if (isUntypedFunctionCall(funcType, apparentType, callSignatures.length, constructSignatures.length)) {
1195811952
// The unknownType indicates that an error already occurred (and was reported). No
1195911953
// need to report another error in this case.
1196011954
if (funcType !== unknownType && node.typeArguments) {
@@ -11977,6 +11971,29 @@ namespace ts {
1197711971
return resolveCall(node, callSignatures, candidatesOutArray);
1197811972
}
1197911973

11974+
/**
11975+
* TS 1.0 spec: 4.12
11976+
* If FuncExpr is of type Any, or of an object type that has no call or construct signatures
11977+
* but is a subtype of the Function interface, the call is an untyped function call.
11978+
*/
11979+
function isUntypedFunctionCall(funcType: Type, apparentFuncType: Type, numCallSignatures: number, numConstructSignatures: number) {
11980+
if (isTypeAny(funcType)) {
11981+
return true;
11982+
}
11983+
if (isTypeAny(apparentFuncType) && funcType.flags & TypeFlags.TypeParameter) {
11984+
return true;
11985+
}
11986+
if (!numCallSignatures && !numConstructSignatures) {
11987+
// We exclude union types because we may have a union of function types that happen to have
11988+
// no common signatures.
11989+
if (funcType.flags & TypeFlags.Union) {
11990+
return false;
11991+
}
11992+
return isTypeAssignableTo(funcType, globalFunctionType);
11993+
}
11994+
return false;
11995+
}
11996+
1198011997
function resolveNewExpression(node: NewExpression, candidatesOutArray: Signature[]): Signature {
1198111998
if (node.arguments && languageVersion < ScriptTarget.ES5) {
1198211999
const spreadIndex = getSpreadArgumentIndex(node.arguments);
@@ -12102,8 +12119,9 @@ namespace ts {
1210212119
}
1210312120

1210412121
const callSignatures = getSignaturesOfType(apparentType, SignatureKind.Call);
12122+
const constructSignatures = getSignaturesOfType(apparentType, SignatureKind.Construct);
1210512123

12106-
if (isTypeAny(tagType) || (!callSignatures.length && !(tagType.flags & TypeFlags.Union) && isTypeAssignableTo(tagType, globalFunctionType))) {
12124+
if (isUntypedFunctionCall(tagType, apparentType, callSignatures.length, constructSignatures.length)) {
1210712125
return resolveUntypedCall(node);
1210812126
}
1210912127

@@ -12148,7 +12166,8 @@ namespace ts {
1214812166
}
1214912167

1215012168
const callSignatures = getSignaturesOfType(apparentType, SignatureKind.Call);
12151-
if (funcType === anyType || (!callSignatures.length && !(funcType.flags & TypeFlags.Union) && isTypeAssignableTo(funcType, globalFunctionType))) {
12169+
const constructSignatures = getSignaturesOfType(apparentType, SignatureKind.Construct);
12170+
if (isUntypedFunctionCall(funcType, apparentType, callSignatures.length, constructSignatures.length)) {
1215212171
return resolveUntypedCall(node);
1215312172
}
1215412173

0 commit comments

Comments
 (0)