From 37c466bfa487aa57be9c9c98b77a1a21a1bfc43e Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 21 Jan 2022 14:19:16 -0800 Subject: [PATCH 01/16] Permit type arguments in references to generic functions --- src/compiler/checker.ts | 65 ++++++++++++++++++++++++++-- src/compiler/diagnosticMessages.json | 4 ++ src/compiler/emitter.ts | 3 ++ src/compiler/factory/nodeFactory.ts | 8 ++-- src/compiler/parser.ts | 48 ++++++++++---------- src/compiler/types.ts | 9 ++-- src/compiler/utilities.ts | 6 +-- src/compiler/utilitiesPublic.ts | 1 + src/compiler/visitorPublic.ts | 3 +- src/services/utilities.ts | 2 +- 10 files changed, 111 insertions(+), 38 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1c93f8ece3101..1712391913a6e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -753,6 +753,7 @@ namespace ts { const templateLiteralTypes = new Map(); const stringMappingTypes = new Map(); const substitutionTypes = new Map(); + const instantiatedFunctionTypes = new Map(); const subtypeReductionCache = new Map(); const evolvingArrayTypes: EvolvingArrayType[] = []; const undefinedProperties: SymbolTable = new Map(); @@ -4569,7 +4570,7 @@ namespace ts { // get symbol of the first identifier of the entityName let meaning: SymbolFlags; if (entityName.parent.kind === SyntaxKind.TypeQuery || - isExpressionWithTypeArgumentsInClassExtendsClause(entityName.parent) || + entityName.parent.kind === SyntaxKind.ExpressionWithTypeArguments && !isPartOfTypeNode(entityName.parent) || entityName.parent.kind === SyntaxKind.ComputedPropertyName) { // Typeof value meaning = SymbolFlags.Value | SymbolFlags.ExportValue; @@ -13635,7 +13636,7 @@ namespace ts { // The expression is processed as an identifier expression (section 4.3) // or property access expression(section 4.10), // the widened type(section 3.9) of which becomes the result. - const type = isThisIdentifier(node.exprName) ? checkThisExpression(node.exprName) : checkExpression(node.exprName); + const type = checkExpressionWithTypeArguments(node); links.resolvedType = getRegularTypeOfLiteralType(getWidenedType(type)); } return links.resolvedType; @@ -31399,6 +31400,62 @@ namespace ts { getNonNullableType(checkExpression(node.expression)); } + function checkExpressionWithTypeArguments(node: ExpressionWithTypeArguments | TypeQueryNode) { + checkGrammarExpressionWithTypeArguments(node); + const exprType = node.kind === SyntaxKind.ExpressionWithTypeArguments ? checkExpression(node.expression) : + isThisIdentifier(node.exprName) ? checkThisExpression(node.exprName) : + checkExpression(node.exprName); + const typeArguments = node.typeArguments; + if (!some(typeArguments)) { + return exprType; + } + let funcType = getApparentType(exprType); + if (funcType === silentNeverType || isErrorType(funcType)) { + return funcType; + } + let signatureMatch = false; + let typeArgumentError = false; + const result = getInstantiatedType(funcType); + if (!signatureMatch) { + diagnostics.add(createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.Type_0_has_no_signatures_for_which_the_type_argument_list_is_applicable, typeToString(funcType))); + return exprType; + } + const key = `${getTypeId(exprType)},${getTypeListId(map(typeArguments, getTypeFromTypeNode))}`; + return instantiatedFunctionTypes.get(key) || (instantiatedFunctionTypes.set(key, result), result); + + function getInstantiatedType(type: Type): Type { + if (type.flags & TypeFlags.Object) { + const resolved = resolveStructuredTypeMembers(type as ObjectType); + const callSignatures = sameMap(filter(resolved.callSignatures, isApplicableSignature), getInstantiatedSignature); + const constructSignatures = sameMap(filter(resolved.constructSignatures, isApplicableSignature), getInstantiatedSignature); + return createAnonymousType(undefined, resolved.members, callSignatures, constructSignatures, resolved.indexInfos); + } + if (type.flags & TypeFlags.Union) { + return mapType(type, getInstantiatedType); + } + if (type.flags & TypeFlags.Intersection) { + return getIntersectionType(sameMap((type as IntersectionType).types, getInstantiatedType)); + } + return type; + } + + function isApplicableSignature(signature: Signature) { + return !!signature.typeParameters && hasCorrectTypeArgumentArity(signature, typeArguments); + } + + function getInstantiatedSignature(signature: Signature) { + if (!typeArgumentError) { + signatureMatch = true; + const typeArgumentTypes = checkTypeArguments(signature, typeArguments!, /*reportErrors*/ true); + if (typeArgumentTypes) { + return getSignatureInstantiation(signature, typeArgumentTypes, isInJSFile(signature.declaration)); + } + typeArgumentError = true; + } + return signature; + } + } + function checkMetaProperty(node: MetaProperty): Type { checkGrammarMetaProperty(node); @@ -34151,6 +34208,8 @@ namespace ts { return checkAssertion(node as AssertionExpression); case SyntaxKind.NonNullExpression: return checkNonNullAssertion(node as NonNullExpression); + case SyntaxKind.ExpressionWithTypeArguments: + return checkExpressionWithTypeArguments(node as ExpressionWithTypeArguments); case SyntaxKind.MetaProperty: return checkMetaProperty(node as MetaProperty); case SyntaxKind.DeleteExpression: @@ -43025,7 +43084,7 @@ namespace ts { return some(types, checkGrammarExpressionWithTypeArguments); } - function checkGrammarExpressionWithTypeArguments(node: ExpressionWithTypeArguments) { + function checkGrammarExpressionWithTypeArguments(node: ExpressionWithTypeArguments | TypeQueryNode) { return checkGrammarTypeArguments(node, node.typeArguments); } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 7438f57dc4a15..c25e7c4d3c659 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2671,6 +2671,10 @@ "category": "Error", "code": 2634 }, + "Type '{0}' has no signatures for which the type argument list is applicable.": { + "category": "Error", + "code": 2635 + }, "Cannot augment module '{0}' with value exports because it resolves to a non-module entity.": { "category": "Error", diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 445537d3de873..7a754aab97431 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1727,6 +1727,8 @@ namespace ts { return emitAsExpression(node as AsExpression); case SyntaxKind.NonNullExpression: return emitNonNullExpression(node as NonNullExpression); + case SyntaxKind.ExpressionWithTypeArguments: + return emitExpressionWithTypeArguments(node as ExpressionWithTypeArguments); case SyntaxKind.MetaProperty: return emitMetaProperty(node as MetaProperty); case SyntaxKind.SyntheticExpression: @@ -2227,6 +2229,7 @@ namespace ts { writeKeyword("typeof"); writeSpace(); emit(node.exprName); + emitTypeArguments(node, node.typeArguments); } function emitTypeLiteral(node: TypeLiteralNode) { diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index 6a20f8069a7fc..dcdb2c8c0ed50 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -1839,17 +1839,19 @@ namespace ts { } // @api - function createTypeQueryNode(exprName: EntityName) { + function createTypeQueryNode(exprName: EntityName, typeArguments?: readonly TypeNode[]) { const node = createBaseNode(SyntaxKind.TypeQuery); node.exprName = exprName; + node.typeArguments = typeArguments && parenthesizerRules().parenthesizeTypeArguments(typeArguments); node.transformFlags = TransformFlags.ContainsTypeScript; return node; } // @api - function updateTypeQueryNode(node: TypeQueryNode, exprName: EntityName) { + function updateTypeQueryNode(node: TypeQueryNode, exprName: EntityName, typeArguments?: readonly TypeNode[]) { return node.exprName !== exprName - ? update(createTypeQueryNode(exprName), node) + || node.typeArguments !== typeArguments + ? update(createTypeQueryNode(exprName, typeArguments), node) : node; } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 420ae33d0b5cd..1d94dfcd1865e 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -180,7 +180,8 @@ namespace ts { visitNode(cbNode, (node as TypePredicateNode).parameterName) || visitNode(cbNode, (node as TypePredicateNode).type); case SyntaxKind.TypeQuery: - return visitNode(cbNode, (node as TypeQueryNode).exprName); + return visitNode(cbNode, (node as TypeQueryNode).exprName) || + visitNodes(cbNode, cbNodes, (node as TypeQueryNode).typeArguments); case SyntaxKind.TypeLiteral: return visitNodes(cbNode, cbNodes, (node as TypeLiteralNode).members); case SyntaxKind.ArrayType: @@ -3078,7 +3079,9 @@ namespace ts { function parseTypeQuery(): TypeQueryNode { const pos = getNodePos(); parseExpected(SyntaxKind.TypeOfKeyword); - return finishNode(factory.createTypeQueryNode(parseEntityName(/*allowReservedWords*/ true)), pos); + const entityName = parseEntityName(/*allowReservedWords*/ true); + const typeArguments = tryParseTypeArguments(); + return finishNode(factory.createTypeQueryNode(entityName, typeArguments), pos); } function parseTypeParameter(): TypeParameterDeclaration { @@ -5485,13 +5488,16 @@ namespace ts { expression = parseTaggedTemplateRest(pos, expression, questionDotToken, typeArguments); continue; } - - const argumentList = parseArgumentList(); - const callExpr = questionDotToken || tryReparseOptionalChain(expression) ? - factory.createCallChain(expression, questionDotToken, typeArguments, argumentList) : - factory.createCallExpression(expression, typeArguments, argumentList); - expression = finishNode(callExpr, pos); - continue; + if (questionDotToken || token() === SyntaxKind.OpenParenToken) { + const argumentList = parseArgumentList(); + const callExpr = questionDotToken || tryReparseOptionalChain(expression) ? + factory.createCallChain(expression, questionDotToken, typeArguments, argumentList) : + factory.createCallExpression(expression, typeArguments, argumentList); + expression = finishNode(callExpr, pos); + continue; + } + expression = finishNode(factory.createExpressionWithTypeArguments(expression, typeArguments), pos); + break; } } else if (token() === SyntaxKind.OpenParenToken) { @@ -5551,6 +5557,7 @@ namespace ts { // these are the only tokens can legally follow a type argument // list. So we definitely want to treat them as type arg lists. // falls through + case SyntaxKind.CommaToken: // foo, case SyntaxKind.DotToken: // foo. case SyntaxKind.CloseParenToken: // foo) case SyntaxKind.CloseBracketToken: // foo] @@ -5574,7 +5581,6 @@ namespace ts { // treat it as such. return true; - case SyntaxKind.CommaToken: // foo, case SyntaxKind.OpenBraceToken: // foo { // We don't want to treat these as type arguments. Otherwise we'll parse this // as an invocation expression. Instead, we want to parse out the expression @@ -5792,18 +5798,13 @@ namespace ts { } const expressionPos = getNodePos(); - let expression: MemberExpression = parsePrimaryExpression(); - let typeArguments; - while (true) { - expression = parseMemberExpressionRest(expressionPos, expression, /*allowOptionalChain*/ false); - typeArguments = tryParse(parseTypeArgumentsInExpression); - if (isTemplateStartOfTaggedTemplate()) { - Debug.assert(!!typeArguments, - "Expected a type argument list; all plain tagged template starts should be consumed in 'parseMemberExpressionRest'"); - expression = parseTaggedTemplateRest(expressionPos, expression, /*optionalChain*/ undefined, typeArguments); - typeArguments = undefined; - } - break; + let expression = parseMemberExpressionRest(expressionPos, parsePrimaryExpression(), /*allowOptionalChain*/ false); + let typeArguments = tryParse(parseTypeArgumentsInExpression); + if (isTemplateStartOfTaggedTemplate()) { + Debug.assert(!!typeArguments, + "Expected a type argument list; all plain tagged template starts should be consumed in 'parseMemberExpressionRest'"); + expression = parseTaggedTemplateRest(expressionPos, expression, /*optionalChain*/ undefined, typeArguments); + typeArguments = undefined; } let argumentsArray: NodeArray | undefined; @@ -7070,6 +7071,9 @@ namespace ts { function parseExpressionWithTypeArguments(): ExpressionWithTypeArguments { const pos = getNodePos(); const expression = parseLeftHandSideExpressionOrHigher(); + if (expression.kind === SyntaxKind.ExpressionWithTypeArguments) { + return expression as ExpressionWithTypeArguments; + } const typeArguments = tryParseTypeArguments(); return finishNode(factory.createExpressionWithTypeArguments(expression, typeArguments), pos); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 7df28d6a42b05..cd03599cdea2d 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -1614,7 +1614,7 @@ namespace ts { readonly type?: TypeNode; } - export interface TypeQueryNode extends TypeNode { + export interface TypeQueryNode extends NodeWithTypeArguments { readonly kind: SyntaxKind.TypeQuery; readonly exprName: EntityName; } @@ -2444,9 +2444,8 @@ namespace ts { readonly expression: ImportExpression; } - export interface ExpressionWithTypeArguments extends NodeWithTypeArguments { + export interface ExpressionWithTypeArguments extends LeftHandSideExpression, NodeWithTypeArguments { readonly kind: SyntaxKind.ExpressionWithTypeArguments; - readonly parent: HeritageClause | JSDocAugmentsTag | JSDocImplementsTag; readonly expression: LeftHandSideExpression; } @@ -7239,8 +7238,8 @@ namespace ts { updateConstructorTypeNode(node: ConstructorTypeNode, modifiers: readonly Modifier[] | undefined, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode): ConstructorTypeNode; /** @deprecated */ updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode): ConstructorTypeNode; - createTypeQueryNode(exprName: EntityName): TypeQueryNode; - updateTypeQueryNode(node: TypeQueryNode, exprName: EntityName): TypeQueryNode; + createTypeQueryNode(exprName: EntityName, typeArguments?: readonly TypeNode[]): TypeQueryNode; + updateTypeQueryNode(node: TypeQueryNode, exprName: EntityName, typeArguments?: readonly TypeNode[]): TypeQueryNode; createTypeLiteralNode(members: readonly TypeElement[] | undefined): TypeLiteralNode; updateTypeLiteralNode(node: TypeLiteralNode, members: NodeArray): TypeLiteralNode; createArrayTypeNode(elementType: TypeNode): ArrayTypeNode; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index aa518d99bab7f..4018ce5936afb 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1279,7 +1279,7 @@ namespace ts { case SyntaxKind.VoidKeyword: return node.parent.kind !== SyntaxKind.VoidExpression; case SyntaxKind.ExpressionWithTypeArguments: - return !isExpressionWithTypeArgumentsInClassExtendsClause(node); + return isHeritageClause(node.parent) && !isExpressionWithTypeArgumentsInClassExtendsClause(node); case SyntaxKind.TypeParameter: return node.parent.kind === SyntaxKind.MappedType || node.parent.kind === SyntaxKind.InferType; @@ -1319,7 +1319,7 @@ namespace ts { } switch (parent.kind) { case SyntaxKind.ExpressionWithTypeArguments: - return !isExpressionWithTypeArgumentsInClassExtendsClause(parent); + return isHeritageClause(parent.parent) && !isExpressionWithTypeArgumentsInClassExtendsClause(parent); case SyntaxKind.TypeParameter: return node === (parent as TypeParameterDeclaration).constraint; case SyntaxKind.JSDocTemplateTag: @@ -2045,7 +2045,7 @@ namespace ts { case SyntaxKind.SpreadAssignment: return true; case SyntaxKind.ExpressionWithTypeArguments: - return (parent as ExpressionWithTypeArguments).expression === node && isExpressionWithTypeArgumentsInClassExtendsClause(parent); + return (parent as ExpressionWithTypeArguments).expression === node && !isPartOfTypeNode(parent); case SyntaxKind.ShorthandPropertyAssignment: return (parent as ShorthandPropertyAssignment).objectAssignmentInitializer === node; default: diff --git a/src/compiler/utilitiesPublic.ts b/src/compiler/utilitiesPublic.ts index 8f834e5e45971..b227a9eb9da9a 100644 --- a/src/compiler/utilitiesPublic.ts +++ b/src/compiler/utilitiesPublic.ts @@ -1531,6 +1531,7 @@ namespace ts { case SyntaxKind.TrueKeyword: case SyntaxKind.SuperKeyword: case SyntaxKind.NonNullExpression: + case SyntaxKind.ExpressionWithTypeArguments: case SyntaxKind.MetaProperty: case SyntaxKind.ImportKeyword: // technically this is only an Expression if it's in a CallExpression return true; diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index 5651ac043d325..81579f235055b 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -538,7 +538,8 @@ namespace ts { case SyntaxKind.TypeQuery: Debug.type(node); return factory.updateTypeQueryNode(node, - nodeVisitor(node.exprName, visitor, isEntityName)); + nodeVisitor(node.exprName, visitor, isEntityName), + nodesVisitor(node.typeArguments, visitor, isTypeNode)); case SyntaxKind.TypeLiteral: Debug.type(node); diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 58cbbfa7c70f0..020d4cd48490f 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -200,7 +200,7 @@ namespace ts { case SyntaxKind.ImportType: return !(node.parent as ImportTypeNode).isTypeOf; case SyntaxKind.ExpressionWithTypeArguments: - return !isExpressionWithTypeArgumentsInClassExtendsClause(node.parent as ExpressionWithTypeArguments); + return isPartOfTypeNode(node.parent); } return false; From 4851407e64e2be5752a0b7c000c6c788be443a97 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 21 Jan 2022 14:26:52 -0800 Subject: [PATCH 02/16] Accept new baselines --- .../reference/api/tsserverlibrary.d.ts | 13 +++++------ tests/baselines/reference/api/typescript.d.ts | 13 +++++------ .../reference/arrayTypeOfTypeOf.errors.txt | 22 ------------------- .../baselines/reference/arrayTypeOfTypeOf.js | 2 -- .../reference/arrayTypeOfTypeOf.types | 8 ++----- .../genericCallWithoutArgs.errors.txt | 9 +++----- .../reference/genericCallWithoutArgs.js | 2 +- .../reference/genericCallWithoutArgs.types | 1 - .../genericCallsWithoutParens.errors.txt | 5 +---- .../reference/genericCallsWithoutParens.js | 2 +- .../reference/genericCallsWithoutParens.types | 3 +-- .../parserMemberAccessExpression1.errors.txt | 22 +++++-------------- .../parserMemberAccessExpression1.js | 6 +++-- .../parserMemberAccessExpression1.types | 2 -- ...erMemberAccessOffOfGenericType1.errors.txt | 16 +++++++------- .../parserMemberAccessOffOfGenericType1.js | 3 ++- ...arserMemberAccessOffOfGenericType1.symbols | 1 + .../parserMemberAccessOffOfGenericType1.types | 4 ++-- .../reference/parserTypeQuery8.errors.txt | 13 ++--------- tests/baselines/reference/parserTypeQuery8.js | 1 - .../reference/parserTypeQuery8.types | 2 -- 21 files changed, 45 insertions(+), 105 deletions(-) delete mode 100644 tests/baselines/reference/arrayTypeOfTypeOf.errors.txt diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 63bad336031ac..7f8e8fb8189b2 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -901,7 +901,7 @@ declare namespace ts { readonly parameterName: Identifier | ThisTypeNode; readonly type?: TypeNode; } - export interface TypeQueryNode extends TypeNode { + export interface TypeQueryNode extends NodeWithTypeArguments { readonly kind: SyntaxKind.TypeQuery; readonly exprName: EntityName; } @@ -1285,9 +1285,8 @@ declare namespace ts { export interface ImportCall extends CallExpression { readonly expression: ImportExpression; } - export interface ExpressionWithTypeArguments extends NodeWithTypeArguments { + export interface ExpressionWithTypeArguments extends LeftHandSideExpression, NodeWithTypeArguments { readonly kind: SyntaxKind.ExpressionWithTypeArguments; - readonly parent: HeritageClause | JSDocAugmentsTag | JSDocImplementsTag; readonly expression: LeftHandSideExpression; } export interface NewExpression extends PrimaryExpression, Declaration { @@ -3392,8 +3391,8 @@ declare namespace ts { updateConstructorTypeNode(node: ConstructorTypeNode, modifiers: readonly Modifier[] | undefined, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode): ConstructorTypeNode; /** @deprecated */ updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode): ConstructorTypeNode; - createTypeQueryNode(exprName: EntityName): TypeQueryNode; - updateTypeQueryNode(node: TypeQueryNode, exprName: EntityName): TypeQueryNode; + createTypeQueryNode(exprName: EntityName, typeArguments?: readonly TypeNode[]): TypeQueryNode; + updateTypeQueryNode(node: TypeQueryNode, exprName: EntityName, typeArguments?: readonly TypeNode[]): TypeQueryNode; createTypeLiteralNode(members: readonly TypeElement[] | undefined): TypeLiteralNode; updateTypeLiteralNode(node: TypeLiteralNode, members: NodeArray): TypeLiteralNode; createArrayTypeNode(elementType: TypeNode): ArrayTypeNode; @@ -10745,9 +10744,9 @@ declare namespace ts { /** @deprecated Use `factory.updateConstructorTypeNode` or the factory supplied by your transformation context instead. */ const updateConstructorTypeNode: (node: ConstructorTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode) => ConstructorTypeNode; /** @deprecated Use `factory.createTypeQueryNode` or the factory supplied by your transformation context instead. */ - const createTypeQueryNode: (exprName: EntityName) => TypeQueryNode; + const createTypeQueryNode: (exprName: EntityName, typeArguments?: readonly TypeNode[] | undefined) => TypeQueryNode; /** @deprecated Use `factory.updateTypeQueryNode` or the factory supplied by your transformation context instead. */ - const updateTypeQueryNode: (node: TypeQueryNode, exprName: EntityName) => TypeQueryNode; + const updateTypeQueryNode: (node: TypeQueryNode, exprName: EntityName, typeArguments?: readonly TypeNode[] | undefined) => TypeQueryNode; /** @deprecated Use `factory.createTypeLiteralNode` or the factory supplied by your transformation context instead. */ const createTypeLiteralNode: (members: readonly TypeElement[] | undefined) => TypeLiteralNode; /** @deprecated Use `factory.updateTypeLiteralNode` or the factory supplied by your transformation context instead. */ diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index fab7e4ba591f5..80c7e5e4b3c8d 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -901,7 +901,7 @@ declare namespace ts { readonly parameterName: Identifier | ThisTypeNode; readonly type?: TypeNode; } - export interface TypeQueryNode extends TypeNode { + export interface TypeQueryNode extends NodeWithTypeArguments { readonly kind: SyntaxKind.TypeQuery; readonly exprName: EntityName; } @@ -1285,9 +1285,8 @@ declare namespace ts { export interface ImportCall extends CallExpression { readonly expression: ImportExpression; } - export interface ExpressionWithTypeArguments extends NodeWithTypeArguments { + export interface ExpressionWithTypeArguments extends LeftHandSideExpression, NodeWithTypeArguments { readonly kind: SyntaxKind.ExpressionWithTypeArguments; - readonly parent: HeritageClause | JSDocAugmentsTag | JSDocImplementsTag; readonly expression: LeftHandSideExpression; } export interface NewExpression extends PrimaryExpression, Declaration { @@ -3392,8 +3391,8 @@ declare namespace ts { updateConstructorTypeNode(node: ConstructorTypeNode, modifiers: readonly Modifier[] | undefined, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode): ConstructorTypeNode; /** @deprecated */ updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode): ConstructorTypeNode; - createTypeQueryNode(exprName: EntityName): TypeQueryNode; - updateTypeQueryNode(node: TypeQueryNode, exprName: EntityName): TypeQueryNode; + createTypeQueryNode(exprName: EntityName, typeArguments?: readonly TypeNode[]): TypeQueryNode; + updateTypeQueryNode(node: TypeQueryNode, exprName: EntityName, typeArguments?: readonly TypeNode[]): TypeQueryNode; createTypeLiteralNode(members: readonly TypeElement[] | undefined): TypeLiteralNode; updateTypeLiteralNode(node: TypeLiteralNode, members: NodeArray): TypeLiteralNode; createArrayTypeNode(elementType: TypeNode): ArrayTypeNode; @@ -6934,9 +6933,9 @@ declare namespace ts { /** @deprecated Use `factory.updateConstructorTypeNode` or the factory supplied by your transformation context instead. */ const updateConstructorTypeNode: (node: ConstructorTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode) => ConstructorTypeNode; /** @deprecated Use `factory.createTypeQueryNode` or the factory supplied by your transformation context instead. */ - const createTypeQueryNode: (exprName: EntityName) => TypeQueryNode; + const createTypeQueryNode: (exprName: EntityName, typeArguments?: readonly TypeNode[] | undefined) => TypeQueryNode; /** @deprecated Use `factory.updateTypeQueryNode` or the factory supplied by your transformation context instead. */ - const updateTypeQueryNode: (node: TypeQueryNode, exprName: EntityName) => TypeQueryNode; + const updateTypeQueryNode: (node: TypeQueryNode, exprName: EntityName, typeArguments?: readonly TypeNode[] | undefined) => TypeQueryNode; /** @deprecated Use `factory.createTypeLiteralNode` or the factory supplied by your transformation context instead. */ const createTypeLiteralNode: (members: readonly TypeElement[] | undefined) => TypeLiteralNode; /** @deprecated Use `factory.updateTypeLiteralNode` or the factory supplied by your transformation context instead. */ diff --git a/tests/baselines/reference/arrayTypeOfTypeOf.errors.txt b/tests/baselines/reference/arrayTypeOfTypeOf.errors.txt deleted file mode 100644 index 2726492f36da3..0000000000000 --- a/tests/baselines/reference/arrayTypeOfTypeOf.errors.txt +++ /dev/null @@ -1,22 +0,0 @@ -tests/cases/conformance/types/specifyingTypes/typeLiterals/arrayTypeOfTypeOf.ts(6,22): error TS1005: ',' expected. -tests/cases/conformance/types/specifyingTypes/typeLiterals/arrayTypeOfTypeOf.ts(6,30): error TS1109: Expression expected. -tests/cases/conformance/types/specifyingTypes/typeLiterals/arrayTypeOfTypeOf.ts(7,22): error TS1005: ',' expected. -tests/cases/conformance/types/specifyingTypes/typeLiterals/arrayTypeOfTypeOf.ts(7,32): error TS1109: Expression expected. - - -==== tests/cases/conformance/types/specifyingTypes/typeLiterals/arrayTypeOfTypeOf.ts (4 errors) ==== - // array type cannot use typeof. - - var x = 1; - var xs: typeof x[]; // Not an error. This is equivalent to Array - var xs2: typeof Array; - var xs3: typeof Array; - ~ -!!! error TS1005: ',' expected. - ~ -!!! error TS1109: Expression expected. - var xs4: typeof Array; - ~ -!!! error TS1005: ',' expected. - ~ -!!! error TS1109: Expression expected. \ No newline at end of file diff --git a/tests/baselines/reference/arrayTypeOfTypeOf.js b/tests/baselines/reference/arrayTypeOfTypeOf.js index ced62a73a0772..74a50b9cc1fc9 100644 --- a/tests/baselines/reference/arrayTypeOfTypeOf.js +++ b/tests/baselines/reference/arrayTypeOfTypeOf.js @@ -13,6 +13,4 @@ var x = 1; var xs; // Not an error. This is equivalent to Array var xs2; var xs3; -; var xs4; -; diff --git a/tests/baselines/reference/arrayTypeOfTypeOf.types b/tests/baselines/reference/arrayTypeOfTypeOf.types index 398cbb759a59f..60eec5fbba21b 100644 --- a/tests/baselines/reference/arrayTypeOfTypeOf.types +++ b/tests/baselines/reference/arrayTypeOfTypeOf.types @@ -14,15 +14,11 @@ var xs2: typeof Array; >Array : ArrayConstructor var xs3: typeof Array; ->xs3 : ArrayConstructor +>xs3 : { (arrayLength: number): number[]; (...items: number[]): number[]; new (arrayLength: number): number[]; new (...items: number[]): number[]; isArray(arg: any): arg is any[]; readonly prototype: any[]; } >Array : ArrayConstructor -> : number -> : any var xs4: typeof Array; ->xs4 : ArrayConstructor +>xs4 : { (arrayLength: number): number[]; (...items: number[]): number[]; new (arrayLength: number): number[]; new (...items: number[]): number[]; isArray(arg: any): arg is any[]; readonly prototype: any[]; } >Array : ArrayConstructor -> : number >x : number -> : any diff --git a/tests/baselines/reference/genericCallWithoutArgs.errors.txt b/tests/baselines/reference/genericCallWithoutArgs.errors.txt index 9d2ca3c1b8350..fe8e0d03e021c 100644 --- a/tests/baselines/reference/genericCallWithoutArgs.errors.txt +++ b/tests/baselines/reference/genericCallWithoutArgs.errors.txt @@ -1,13 +1,10 @@ -tests/cases/compiler/genericCallWithoutArgs.ts(4,17): error TS1005: '(' expected. -tests/cases/compiler/genericCallWithoutArgs.ts(4,18): error TS1005: ')' expected. +tests/cases/compiler/genericCallWithoutArgs.ts(4,17): error TS1005: ';' expected. -==== tests/cases/compiler/genericCallWithoutArgs.ts (2 errors) ==== +==== tests/cases/compiler/genericCallWithoutArgs.ts (1 errors) ==== function f(x: X, y: Y) { } f. ~ -!!! error TS1005: '(' expected. - -!!! error TS1005: ')' expected. \ No newline at end of file +!!! error TS1005: ';' expected. \ No newline at end of file diff --git a/tests/baselines/reference/genericCallWithoutArgs.js b/tests/baselines/reference/genericCallWithoutArgs.js index abf947a7d3b58..0e4d8446f999c 100644 --- a/tests/baselines/reference/genericCallWithoutArgs.js +++ b/tests/baselines/reference/genericCallWithoutArgs.js @@ -7,4 +7,4 @@ f. //// [genericCallWithoutArgs.js] function f(x, y) { } -f(); +f; diff --git a/tests/baselines/reference/genericCallWithoutArgs.types b/tests/baselines/reference/genericCallWithoutArgs.types index 7f9565df8a68c..54302dde335d4 100644 --- a/tests/baselines/reference/genericCallWithoutArgs.types +++ b/tests/baselines/reference/genericCallWithoutArgs.types @@ -6,6 +6,5 @@ function f(x: X, y: Y) { } f. ->f. : void >f : (x: X, y: Y) => void diff --git a/tests/baselines/reference/genericCallsWithoutParens.errors.txt b/tests/baselines/reference/genericCallsWithoutParens.errors.txt index aa53a586d8867..fd5a285102bfb 100644 --- a/tests/baselines/reference/genericCallsWithoutParens.errors.txt +++ b/tests/baselines/reference/genericCallsWithoutParens.errors.txt @@ -1,12 +1,9 @@ -tests/cases/compiler/genericCallsWithoutParens.ts(2,18): error TS1005: '(' expected. tests/cases/compiler/genericCallsWithoutParens.ts(7,8): error TS1384: A 'new' expression with type arguments must always be followed by a parenthesized argument list. -==== tests/cases/compiler/genericCallsWithoutParens.ts (2 errors) ==== +==== tests/cases/compiler/genericCallsWithoutParens.ts (1 errors) ==== function f() { } var r = f; // parse error - ~ -!!! error TS1005: '(' expected. class C { foo: T; diff --git a/tests/baselines/reference/genericCallsWithoutParens.js b/tests/baselines/reference/genericCallsWithoutParens.js index 99e29292e6ada..83c44aead0773 100644 --- a/tests/baselines/reference/genericCallsWithoutParens.js +++ b/tests/baselines/reference/genericCallsWithoutParens.js @@ -11,7 +11,7 @@ var c = new C; // parse error //// [genericCallsWithoutParens.js] function f() { } -var r = f(); // parse error +var r = (f); // parse error var C = /** @class */ (function () { function C() { } diff --git a/tests/baselines/reference/genericCallsWithoutParens.types b/tests/baselines/reference/genericCallsWithoutParens.types index 1364fc6135a40..ad7f404599f1e 100644 --- a/tests/baselines/reference/genericCallsWithoutParens.types +++ b/tests/baselines/reference/genericCallsWithoutParens.types @@ -3,8 +3,7 @@ function f() { } >f : () => void var r = f; // parse error ->r : void ->f : void +>r : () => void >f : () => void class C { diff --git a/tests/baselines/reference/parserMemberAccessExpression1.errors.txt b/tests/baselines/reference/parserMemberAccessExpression1.errors.txt index 4e3e41770fe12..5920aa121956f 100644 --- a/tests/baselines/reference/parserMemberAccessExpression1.errors.txt +++ b/tests/baselines/reference/parserMemberAccessExpression1.errors.txt @@ -3,19 +3,15 @@ tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(2,1): error TS2304: Cannot find name 'Foo'. tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(2,9): error TS2304: Cannot find name 'T'. tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(3,1): error TS2304: Cannot find name 'Foo'. -tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(3,5): error TS2304: Cannot find name 'T'. -tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(3,7): error TS1005: '(' expected. +tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(3,7): error TS1005: ';' expected. tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(3,8): error TS2304: Cannot find name 'Bar'. -tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(3,13): error TS1005: ')' expected. tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(4,1): error TS2304: Cannot find name 'Foo'. -tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(4,5): error TS2304: Cannot find name 'T'. -tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(4,7): error TS1005: '(' expected. +tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(4,7): error TS1005: ';' expected. tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(4,8): error TS2304: Cannot find name 'Bar'. tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(4,12): error TS2304: Cannot find name 'T'. -tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(4,16): error TS1005: ')' expected. -==== tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts (15 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts (11 errors) ==== Foo(); ~~~ !!! error TS2304: Cannot find name 'Foo'. @@ -29,25 +25,17 @@ tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression Foo.Bar(); ~~~ !!! error TS2304: Cannot find name 'Foo'. - ~ -!!! error TS2304: Cannot find name 'T'. ~ -!!! error TS1005: '(' expected. +!!! error TS1005: ';' expected. ~~~ !!! error TS2304: Cannot find name 'Bar'. - ~ -!!! error TS1005: ')' expected. Foo.Bar(); ~~~ !!! error TS2304: Cannot find name 'Foo'. - ~ -!!! error TS2304: Cannot find name 'T'. ~ -!!! error TS1005: '(' expected. +!!! error TS1005: ';' expected. ~~~ !!! error TS2304: Cannot find name 'Bar'. ~ !!! error TS2304: Cannot find name 'T'. - ~ -!!! error TS1005: ')' expected. \ No newline at end of file diff --git a/tests/baselines/reference/parserMemberAccessExpression1.js b/tests/baselines/reference/parserMemberAccessExpression1.js index 83897e27097f4..63ad3a4c7e879 100644 --- a/tests/baselines/reference/parserMemberAccessExpression1.js +++ b/tests/baselines/reference/parserMemberAccessExpression1.js @@ -8,5 +8,7 @@ Foo.Bar(); //// [parserMemberAccessExpression1.js] Foo(); Foo.Bar(); -Foo(Bar()); -Foo(Bar()); +Foo; +Bar(); +Foo; +Bar(); diff --git a/tests/baselines/reference/parserMemberAccessExpression1.types b/tests/baselines/reference/parserMemberAccessExpression1.types index 28ccd11641bab..db1c874c84c97 100644 --- a/tests/baselines/reference/parserMemberAccessExpression1.types +++ b/tests/baselines/reference/parserMemberAccessExpression1.types @@ -10,13 +10,11 @@ Foo.Bar(); >Bar : any Foo.Bar(); ->Foo.Bar() : any >Foo : any >Bar() : any >Bar : any Foo.Bar(); ->Foo.Bar() : any >Foo : any >Bar() : any >Bar : any diff --git a/tests/baselines/reference/parserMemberAccessOffOfGenericType1.errors.txt b/tests/baselines/reference/parserMemberAccessOffOfGenericType1.errors.txt index e65adecee3a7b..fe67401732ad5 100644 --- a/tests/baselines/reference/parserMemberAccessOffOfGenericType1.errors.txt +++ b/tests/baselines/reference/parserMemberAccessOffOfGenericType1.errors.txt @@ -1,7 +1,7 @@ tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGenericType1.ts(1,9): error TS2304: Cannot find name 'List'. -tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGenericType1.ts(1,21): error TS1005: '(' expected. -tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGenericType1.ts(1,22): error TS2304: Cannot find name 'makeChild'. -tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGenericType1.ts(1,33): error TS1005: ')' expected. +tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGenericType1.ts(1,21): error TS1005: ',' expected. +tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGenericType1.ts(1,31): error TS1005: ',' expected. +tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGenericType1.ts(1,32): error TS1109: Expression expected. ==== tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGenericType1.ts (4 errors) ==== @@ -9,8 +9,8 @@ tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGener ~~~~ !!! error TS2304: Cannot find name 'List'. ~ -!!! error TS1005: '(' expected. - ~~~~~~~~~ -!!! error TS2304: Cannot find name 'makeChild'. - ~ -!!! error TS1005: ')' expected. \ No newline at end of file +!!! error TS1005: ',' expected. + ~ +!!! error TS1005: ',' expected. + ~ +!!! error TS1109: Expression expected. \ No newline at end of file diff --git a/tests/baselines/reference/parserMemberAccessOffOfGenericType1.js b/tests/baselines/reference/parserMemberAccessOffOfGenericType1.js index 4529fafba0257..eb0a0b94a0594 100644 --- a/tests/baselines/reference/parserMemberAccessOffOfGenericType1.js +++ b/tests/baselines/reference/parserMemberAccessOffOfGenericType1.js @@ -2,4 +2,5 @@ var v = List.makeChild(); //// [parserMemberAccessOffOfGenericType1.js] -var v = List(makeChild()); +var v = (List), makeChild; +(); diff --git a/tests/baselines/reference/parserMemberAccessOffOfGenericType1.symbols b/tests/baselines/reference/parserMemberAccessOffOfGenericType1.symbols index ab2eff6445126..5813f78e326af 100644 --- a/tests/baselines/reference/parserMemberAccessOffOfGenericType1.symbols +++ b/tests/baselines/reference/parserMemberAccessOffOfGenericType1.symbols @@ -1,4 +1,5 @@ === tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGenericType1.ts === var v = List.makeChild(); >v : Symbol(v, Decl(parserMemberAccessOffOfGenericType1.ts, 0, 3)) +>makeChild : Symbol(makeChild, Decl(parserMemberAccessOffOfGenericType1.ts, 0, 21)) diff --git a/tests/baselines/reference/parserMemberAccessOffOfGenericType1.types b/tests/baselines/reference/parserMemberAccessOffOfGenericType1.types index 2df0af23e9550..2b73261a99e46 100644 --- a/tests/baselines/reference/parserMemberAccessOffOfGenericType1.types +++ b/tests/baselines/reference/parserMemberAccessOffOfGenericType1.types @@ -1,8 +1,8 @@ === tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGenericType1.ts === var v = List.makeChild(); >v : any ->List.makeChild() : any >List : any ->makeChild() : any >makeChild : any +>() : any +> : any diff --git a/tests/baselines/reference/parserTypeQuery8.errors.txt b/tests/baselines/reference/parserTypeQuery8.errors.txt index 49582f8d1dd9f..ab24604ba90fa 100644 --- a/tests/baselines/reference/parserTypeQuery8.errors.txt +++ b/tests/baselines/reference/parserTypeQuery8.errors.txt @@ -1,16 +1,7 @@ tests/cases/conformance/parser/ecmascript5/Types/parserTypeQuery8.ts(1,15): error TS2304: Cannot find name 'A'. -tests/cases/conformance/parser/ecmascript5/Types/parserTypeQuery8.ts(1,16): error TS1005: ',' expected. -tests/cases/conformance/parser/ecmascript5/Types/parserTypeQuery8.ts(1,17): error TS2304: Cannot find name 'B'. -tests/cases/conformance/parser/ecmascript5/Types/parserTypeQuery8.ts(1,19): error TS1109: Expression expected. -==== tests/cases/conformance/parser/ecmascript5/Types/parserTypeQuery8.ts (4 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/Types/parserTypeQuery8.ts (1 errors) ==== var v: typeof A ~ -!!! error TS2304: Cannot find name 'A'. - ~ -!!! error TS1005: ',' expected. - ~ -!!! error TS2304: Cannot find name 'B'. - -!!! error TS1109: Expression expected. \ No newline at end of file +!!! error TS2304: Cannot find name 'A'. \ No newline at end of file diff --git a/tests/baselines/reference/parserTypeQuery8.js b/tests/baselines/reference/parserTypeQuery8.js index 0600a038db09a..f0fd7d6212e76 100644 --- a/tests/baselines/reference/parserTypeQuery8.js +++ b/tests/baselines/reference/parserTypeQuery8.js @@ -3,4 +3,3 @@ var v: typeof A //// [parserTypeQuery8.js] var v; -; diff --git a/tests/baselines/reference/parserTypeQuery8.types b/tests/baselines/reference/parserTypeQuery8.types index a2822af8fc6bd..4d92a64d85137 100644 --- a/tests/baselines/reference/parserTypeQuery8.types +++ b/tests/baselines/reference/parserTypeQuery8.types @@ -2,6 +2,4 @@ var v: typeof A >v : any >A : any -> : B -> : any From 0baf6566632b58cf3fa9ffc461657f4977b70182 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 21 Jan 2022 17:39:26 -0800 Subject: [PATCH 03/16] Delete pointless fourslash test --- tests/cases/fourslash/smartIndentTypeArgumentList.ts | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 tests/cases/fourslash/smartIndentTypeArgumentList.ts diff --git a/tests/cases/fourslash/smartIndentTypeArgumentList.ts b/tests/cases/fourslash/smartIndentTypeArgumentList.ts deleted file mode 100644 index 24136596ed1f9..0000000000000 --- a/tests/cases/fourslash/smartIndentTypeArgumentList.ts +++ /dev/null @@ -1,8 +0,0 @@ -/// - -////interface T1 extends T - -goTo.marker(); -verify.indentationIs(32); \ No newline at end of file From 61a2de0eeb890b4871cc6efb06150dbd6a106d93 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 21 Jan 2022 17:50:18 -0800 Subject: [PATCH 04/16] Fix lint issue --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1712391913a6e..97bdc51199183 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -31409,7 +31409,7 @@ namespace ts { if (!some(typeArguments)) { return exprType; } - let funcType = getApparentType(exprType); + const funcType = getApparentType(exprType); if (funcType === silentNeverType || isErrorType(funcType)) { return funcType; } From d50197cd5f410dd6e1179d1469d1ef44d20bb1cd Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 25 Jan 2022 10:34:22 -0800 Subject: [PATCH 05/16] Finalize implementation --- src/compiler/checker.ts | 62 ++++++++++++++++++++++------------------- src/compiler/parser.ts | 30 ++++++++------------ 2 files changed, 45 insertions(+), 47 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 97bdc51199183..9114d1cf72cae 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -31413,46 +31413,52 @@ namespace ts { if (funcType === silentNeverType || isErrorType(funcType)) { return funcType; } - let signatureMatch = false; - let typeArgumentError = false; - const result = getInstantiatedType(funcType); - if (!signatureMatch) { - diagnostics.add(createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.Type_0_has_no_signatures_for_which_the_type_argument_list_is_applicable, typeToString(funcType))); - return exprType; + let hasSomeApplicableSignature = false; + let nonApplicableType: Type | undefined; + let hasSignatures: boolean; + let hasApplicableSignature: boolean; + const result = mapType(funcType, getInstantiatedType); + const errorType = hasSomeApplicableSignature ? nonApplicableType : funcType; + if (errorType) { + diagnostics.add(createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.Type_0_has_no_signatures_for_which_the_type_argument_list_is_applicable, typeToString(errorType))); } const key = `${getTypeId(exprType)},${getTypeListId(map(typeArguments, getTypeFromTypeNode))}`; return instantiatedFunctionTypes.get(key) || (instantiatedFunctionTypes.set(key, result), result); function getInstantiatedType(type: Type): Type { + hasSignatures = false; + hasApplicableSignature = false; + const result = getInstantiatedTypeWorker(type); + hasSomeApplicableSignature ||= hasApplicableSignature; + if (hasSignatures && !hasApplicableSignature) { + nonApplicableType ??= type; + } + return result; + } + + function getInstantiatedTypeWorker(type: Type): Type { if (type.flags & TypeFlags.Object) { const resolved = resolveStructuredTypeMembers(type as ObjectType); - const callSignatures = sameMap(filter(resolved.callSignatures, isApplicableSignature), getInstantiatedSignature); - const constructSignatures = sameMap(filter(resolved.constructSignatures, isApplicableSignature), getInstantiatedSignature); - return createAnonymousType(undefined, resolved.members, callSignatures, constructSignatures, resolved.indexInfos); - } - if (type.flags & TypeFlags.Union) { - return mapType(type, getInstantiatedType); + const callSignatures = getInstantiatedSignatures(resolved.callSignatures); + const constructSignatures = getInstantiatedSignatures(resolved.constructSignatures); + hasSignatures ||= resolved.callSignatures.length !== 0 || resolved.constructSignatures.length !== 0; + hasApplicableSignature ||= callSignatures.length !== 0 || constructSignatures.length !== 0; + if (callSignatures !== resolved.callSignatures || constructSignatures !== resolved.constructSignatures) { + return createAnonymousType(undefined, resolved.members, callSignatures, constructSignatures, resolved.indexInfos); + } } - if (type.flags & TypeFlags.Intersection) { - return getIntersectionType(sameMap((type as IntersectionType).types, getInstantiatedType)); + else if (type.flags & TypeFlags.Intersection) { + return getIntersectionType(sameMap((type as IntersectionType).types, getInstantiatedTypeWorker)); } return type; } - function isApplicableSignature(signature: Signature) { - return !!signature.typeParameters && hasCorrectTypeArgumentArity(signature, typeArguments); - } - - function getInstantiatedSignature(signature: Signature) { - if (!typeArgumentError) { - signatureMatch = true; - const typeArgumentTypes = checkTypeArguments(signature, typeArguments!, /*reportErrors*/ true); - if (typeArgumentTypes) { - return getSignatureInstantiation(signature, typeArgumentTypes, isInJSFile(signature.declaration)); - } - typeArgumentError = true; - } - return signature; + function getInstantiatedSignatures(signatures: readonly Signature[]) { + const applicableSignatures = filter(signatures, sig => !!sig.typeParameters && hasCorrectTypeArgumentArity(sig, typeArguments)); + return sameMap(applicableSignatures, sig => { + const typeArgumentTypes = checkTypeArguments(sig, typeArguments!, /*reportErrors*/ true); + return typeArgumentTypes ? getSignatureInstantiation(sig, typeArgumentTypes, isInJSFile(sig.declaration)) : sig; + }); } } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 1d94dfcd1865e..8392efa650d28 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -5542,20 +5542,22 @@ namespace ts { return undefined; } - // If we have a '<', then only parse this as a argument list if the type arguments - // are complete and we have an open paren. if we don't, rewind and return nothing. - return typeArguments && canFollowTypeArgumentsInExpression() - ? typeArguments - : undefined; + // We successfully parsed a type argument list. The next token determines whether we want to + // treat it as such. If the type argument list is followed by `(` or a template literal, as in + // `f(42)`, we favor the type argument interpretation even though JavaScript would view + // it as a relational expression. + return typeArguments && canFollowTypeArgumentsInExpression() ? typeArguments : undefined; } function canFollowTypeArgumentsInExpression(): boolean { switch (token()) { + // These tokens can follow a type argument list in a call expression. case SyntaxKind.OpenParenToken: // foo( case SyntaxKind.NoSubstitutionTemplateLiteral: // foo `...` case SyntaxKind.TemplateHead: // foo `...${100}...` - // these are the only tokens can legally follow a type argument - // list. So we definitely want to treat them as type arg lists. + // These tokens can't follow in a call expression, nor can they start an + // expression. So, consider the type argument list part of an instantiation + // expression. // falls through case SyntaxKind.CommaToken: // foo, case SyntaxKind.DotToken: // foo. @@ -5576,20 +5578,10 @@ namespace ts { case SyntaxKind.BarToken: // foo | case SyntaxKind.CloseBraceToken: // foo } case SyntaxKind.EndOfFileToken: // foo - // these cases can't legally follow a type arg list. However, they're not legal - // expressions either. The user is probably in the middle of a generic type. So - // treat it as such. return true; - - case SyntaxKind.OpenBraceToken: // foo { - // We don't want to treat these as type arguments. Otherwise we'll parse this - // as an invocation expression. Instead, we want to parse out the expression - // in isolation from the type arguments. - // falls through - default: - // Anything else treat as an expression. - return false; } + // Treat anything else as an expression. + return false; } function parsePrimaryExpression(): PrimaryExpression { From 1411a2ea0ea924fb18aca8bc7cb2daf547833432 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 25 Jan 2022 10:34:37 -0800 Subject: [PATCH 06/16] Add tests --- .../instantiationExpressionErrors.ts | 32 +++++ .../instantiationExpressions.ts | 134 ++++++++++++++++++ 2 files changed, 166 insertions(+) create mode 100644 tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts create mode 100644 tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts diff --git a/tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts b/tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts new file mode 100644 index 0000000000000..835524ba9ea66 --- /dev/null +++ b/tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts @@ -0,0 +1,32 @@ +// @strict: true +// @declaration: true + +declare let f: any; + +// Type arguments only permitted at end of member expression + +const a1 = f; +const a2 = f.g; +const a3 = f.g; +const a4 = f.g; + +// Type arguments must follow ?. token + +const b1 = f?.; +const b2 = f?.(); +const b3 = f?.(); + +// Parsed as function call, even though this differs from JavaScript + +const x1 = f +(true); + +// Parsed as relational expression + +const x2 = f +true; + +// Parsed as instantiation expression + +const x3 = f; +true; diff --git a/tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts b/tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts new file mode 100644 index 0000000000000..793cbf765b17e --- /dev/null +++ b/tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts @@ -0,0 +1,134 @@ +// @strict: true +// @declaration: true + +declare function fx(x: T): T; +declare function fx(x: T, n: number): T; +declare function fx(t: [T, U]): [T, U]; + +function f1() { + let f0 = fx<>; // Error + let f1 = fx; // { (x: string): string; (x: string, n: number): string; } + let f2 = fx; // (t: [string, number]) => [string, number] + let f3 = fx; // Error +} + +type T10 = typeof fx<>; // Error +type T11 = typeof fx; // { (x: string): string; (x: string, n: number): string; } +type T12 = typeof fx; // (t: [string, number]) => [string, number] +type T13 = typeof fx; // Error + +function f2() { + const A0 = Array<>; // Error + const A1 = Array; // new (...) => string[] + const A2 = Array; // Error +} + +type T20 = typeof Array<>; // Error +type T21 = typeof Array; // new (...) => string[] +type T22 = typeof Array; // Error + +declare class C { + constructor(x: T); + static f(x: U): U[]; +} + +function f3() { + let c1 = C; // { new (x: string): C; f(x: U): T[]; prototype: C; } + let f1 = C.f; // (x: string) => string[] +} + +function f10(f: { (a: T): T, (a: U, b: number): U[] }) { + let fs = f; // { (a: string): string; (a: string, b: number): string[]; } +} + +function f11(f: { (a: T): T, (a: string, b: number): string[] }) { + let fs = f; // (a: string) => string +} + +function f12(f: { (a: T): T, x: string }) { + let fs = f; // { (a: string): string; x: string; } +} + +function f13(f: { x: string, y: string }) { + let fs = f; // Error, no applicable signatures +} + +function f14(f: { new (a: T): T, new (a: U, b: number): U[] }) { + let fs = f; // { new (a: string): string; new (a: string, b: number): string[]; } +} + +function f15(f: { new (a: T): T, (a: U, b: number): U[] }) { + let fs = f; // { new (a: string): string; (a: string, b: number): string[]; } +} + +function f16(f: { new (a: T): T, (a: string, b: number): string[] }) { + let fs = f; // new (a: string) => string +} + +function f17(f: { (a: T): T, new (a: string, b: number): string[] }) { + let fs = f; // (a: string) => string +} + +function f20(f: ((a: T) => T) & ((a: U, b: number) => U[])) { + let fs = f; // ((a: string) => string) & ((a: string, b: number) => string[]]) +} + +function f21(f: ((a: T) => T) & ((a: string, b: number) => string[])) { + let fs = f; // (a: string) => string +} + +function f22(f: ((a: T) => T) & { x: string }) { + let fs = f; // ((a: string) => string) & { x: string } +} + +function f23(f: { x: string } & { y: string }) { + let fs = f; // Error, no applicable signatures +} + +function f24(f: (new (a: T) => T) & (new (a: U, b: number) => U[])) { + let fs = f; // (new (a: string) => string) & ((a: string, b: number) => string[]]) +} + +function f25(f: (new (a: T) => T) & ((a: U, b: number) => U[])) { + let fs = f; // (new (a: string) => string) & ((a: string, b: number) => string[]]) +} + +function f26(f: (new (a: T) => T) & ((a: string, b: number) => string[])) { + let fs = f; // new (a: string) => string +} + +function f27(f: ((a: T) => T) & (new (a: string, b: number) => string[])) { + let fs = f; // (a: string) => string +} + +function f30(f: ((a: T) => T) | ((a: U, b: number) => U[])) { + let fs = f; // ((a: string) => string) | ((a: string, b: number) => string[]]) +} + +function f31(f: ((a: T) => T) | ((a: string, b: number) => string[])) { + let fs = f; // Error, '(a: string, b: number) => string[]' has no applicable signatures +} + +function f32(f: ((a: T) => T) | { x: string }) { + let fs = f; // ((a: string) => string) | { x: string } +} + +function f33(f: { x: string } | { y: string }) { + let fs = f; // Error, no applicable signatures +} + +function f34(f: (new (a: T) => T) | (new (a: U, b: number) => U[])) { + let fs = f; // (new (a: string) => string) | ((a: string, b: number) => string[]]) +} + +function f35(f: (new (a: T) => T) | ((a: U, b: number) => U[])) { + let fs = f; // (new (a: string) => string) | ((a: string, b: number) => string[]]) +} + +function f36(f: (new (a: T) => T) | ((a: string, b: number) => string[])) { + let fs = f; // Error, '(a: string, b: number) => string[]' has no applicable signatures +} + +function f37(f: ((a: T) => T) | (new (a: string, b: number) => string[])) { + let fs = f; // Error, 'new (a: string, b: number) => string[]' has no applicable signatures +} From fa0d15503de4e95d3eb68e93f24568bdfe06bb5b Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 25 Jan 2022 10:34:45 -0800 Subject: [PATCH 07/16] Accept new baselines --- .../instantiationExpressionErrors.errors.txt | 91 ++++ .../instantiationExpressionErrors.js | 66 +++ .../instantiationExpressionErrors.symbols | 62 +++ .../instantiationExpressionErrors.types | 82 +++ .../instantiationExpressions.errors.txt | 177 +++++++ .../reference/instantiationExpressions.js | 303 +++++++++++ .../instantiationExpressions.symbols | 492 ++++++++++++++++++ .../reference/instantiationExpressions.types | 385 ++++++++++++++ 8 files changed, 1658 insertions(+) create mode 100644 tests/baselines/reference/instantiationExpressionErrors.errors.txt create mode 100644 tests/baselines/reference/instantiationExpressionErrors.js create mode 100644 tests/baselines/reference/instantiationExpressionErrors.symbols create mode 100644 tests/baselines/reference/instantiationExpressionErrors.types create mode 100644 tests/baselines/reference/instantiationExpressions.errors.txt create mode 100644 tests/baselines/reference/instantiationExpressions.js create mode 100644 tests/baselines/reference/instantiationExpressions.symbols create mode 100644 tests/baselines/reference/instantiationExpressions.types diff --git a/tests/baselines/reference/instantiationExpressionErrors.errors.txt b/tests/baselines/reference/instantiationExpressionErrors.errors.txt new file mode 100644 index 0000000000000..7cd0ad52d97bb --- /dev/null +++ b/tests/baselines/reference/instantiationExpressionErrors.errors.txt @@ -0,0 +1,91 @@ +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(5,14): error TS2635: Type 'any' has no signatures for which the type argument list is applicable. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(6,16): error TS2635: Type 'any' has no signatures for which the type argument list is applicable. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(7,14): error TS2635: Type 'any' has no signatures for which the type argument list is applicable. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(7,21): error TS1005: ',' expected. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(7,22): error TS2451: Cannot redeclare block-scoped variable 'g'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(7,22): error TS7005: Variable 'g' implicitly has an 'any' type. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(8,14): error TS2635: Type 'any' has no signatures for which the type argument list is applicable. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(8,21): error TS1005: ',' expected. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(8,22): error TS2451: Cannot redeclare block-scoped variable 'g'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(8,22): error TS7005: Variable 'g' implicitly has an 'any' type. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(8,23): error TS1005: ',' expected. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(8,31): error TS1109: Expression expected. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(12,12): error TS2347: Untyped function calls may not accept type arguments. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(12,23): error TS1005: '(' expected. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(13,12): error TS2347: Untyped function calls may not accept type arguments. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(14,14): error TS2693: 'number' only refers to a type, but is being used as a value here. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(14,21): error TS1109: Expression expected. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(18,12): error TS2347: Untyped function calls may not accept type arguments. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(28,14): error TS2635: Type 'any' has no signatures for which the type argument list is applicable. + + +==== tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts (19 errors) ==== + declare let f: any; + + // Type arguments only permitted at end of member expression + + const a1 = f; + ~~~~~~ +!!! error TS2635: Type 'any' has no signatures for which the type argument list is applicable. + const a2 = f.g; + ~~~~~~ +!!! error TS2635: Type 'any' has no signatures for which the type argument list is applicable. + const a3 = f.g; + ~~~~~~ +!!! error TS2635: Type 'any' has no signatures for which the type argument list is applicable. + ~ +!!! error TS1005: ',' expected. + ~ +!!! error TS2451: Cannot redeclare block-scoped variable 'g'. + ~ +!!! error TS7005: Variable 'g' implicitly has an 'any' type. + const a4 = f.g; + ~~~~~~ +!!! error TS2635: Type 'any' has no signatures for which the type argument list is applicable. + ~ +!!! error TS1005: ',' expected. + ~ +!!! error TS2451: Cannot redeclare block-scoped variable 'g'. + ~ +!!! error TS7005: Variable 'g' implicitly has an 'any' type. + ~ +!!! error TS1005: ',' expected. + ~ +!!! error TS1109: Expression expected. + + // Type arguments must follow ?. token + + const b1 = f?.; + ~~~~~~~~~~~ +!!! error TS2347: Untyped function calls may not accept type arguments. + ~ +!!! error TS1005: '(' expected. + const b2 = f?.(); + ~~~~~~~~~~~~~ +!!! error TS2347: Untyped function calls may not accept type arguments. + const b3 = f?.(); + ~~~~~~ +!!! error TS2693: 'number' only refers to a type, but is being used as a value here. + ~~ +!!! error TS1109: Expression expected. + + // Parsed as function call, even though this differs from JavaScript + + const x1 = f + ~~~~~~~ + (true); + ~~~~~~ +!!! error TS2347: Untyped function calls may not accept type arguments. + + // Parsed as relational expression + + const x2 = f + true; + + // Parsed as instantiation expression + + const x3 = f; + ~~~~ +!!! error TS2635: Type 'any' has no signatures for which the type argument list is applicable. + true; + \ No newline at end of file diff --git a/tests/baselines/reference/instantiationExpressionErrors.js b/tests/baselines/reference/instantiationExpressionErrors.js new file mode 100644 index 0000000000000..a0324d186a7e9 --- /dev/null +++ b/tests/baselines/reference/instantiationExpressionErrors.js @@ -0,0 +1,66 @@ +//// [instantiationExpressionErrors.ts] +declare let f: any; + +// Type arguments only permitted at end of member expression + +const a1 = f; +const a2 = f.g; +const a3 = f.g; +const a4 = f.g; + +// Type arguments must follow ?. token + +const b1 = f?.; +const b2 = f?.(); +const b3 = f?.(); + +// Parsed as function call, even though this differs from JavaScript + +const x1 = f +(true); + +// Parsed as relational expression + +const x2 = f +true; + +// Parsed as instantiation expression + +const x3 = f; +true; + + +//// [instantiationExpressionErrors.js] +"use strict"; +// Type arguments only permitted at end of member expression +var a1 = (f); +var a2 = (f.g); +var a3 = (f), g; +var a4 = (f), g; +; +// Type arguments must follow ?. token +var b1 = f === null || f === void 0 ? void 0 : f(); +var b2 = f === null || f === void 0 ? void 0 : f(); +var b3 = f < number > ( === null || === void 0 ? void 0 : ()); +// Parsed as function call, even though this differs from JavaScript +var x1 = f(true); +// Parsed as relational expression +var x2 = f < true > + true; +// Parsed as instantiation expression +var x3 = (f); +true; + + +//// [instantiationExpressionErrors.d.ts] +declare let f: any; +declare const a1: any; +declare const a2: any; +declare const a3: any, g: any; +declare const a4: any, g: any; +declare const b1: any; +declare const b2: any; +declare const b3: boolean; +declare const x1: any; +declare const x2: boolean; +declare const x3: any; diff --git a/tests/baselines/reference/instantiationExpressionErrors.symbols b/tests/baselines/reference/instantiationExpressionErrors.symbols new file mode 100644 index 0000000000000..2e44a94bdaf7b --- /dev/null +++ b/tests/baselines/reference/instantiationExpressionErrors.symbols @@ -0,0 +1,62 @@ +=== tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts === +declare let f: any; +>f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) + +// Type arguments only permitted at end of member expression + +const a1 = f; +>a1 : Symbol(a1, Decl(instantiationExpressionErrors.ts, 4, 5)) +>f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) + +const a2 = f.g; +>a2 : Symbol(a2, Decl(instantiationExpressionErrors.ts, 5, 5)) +>f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) + +const a3 = f.g; +>a3 : Symbol(a3, Decl(instantiationExpressionErrors.ts, 6, 5)) +>f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) +>g : Symbol(g, Decl(instantiationExpressionErrors.ts, 6, 21)) + +const a4 = f.g; +>a4 : Symbol(a4, Decl(instantiationExpressionErrors.ts, 7, 5)) +>f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) +>g : Symbol(g, Decl(instantiationExpressionErrors.ts, 7, 21)) + +// Type arguments must follow ?. token + +const b1 = f?.; +>b1 : Symbol(b1, Decl(instantiationExpressionErrors.ts, 11, 5)) +>f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) + +const b2 = f?.(); +>b2 : Symbol(b2, Decl(instantiationExpressionErrors.ts, 12, 5)) +>f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) + +const b3 = f?.(); +>b3 : Symbol(b3, Decl(instantiationExpressionErrors.ts, 13, 5)) +>f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) + +// Parsed as function call, even though this differs from JavaScript + +const x1 = f +>x1 : Symbol(x1, Decl(instantiationExpressionErrors.ts, 17, 5)) +>f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) + +(true); + +// Parsed as relational expression + +const x2 = f +>x2 : Symbol(x2, Decl(instantiationExpressionErrors.ts, 22, 5)) +>f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) + +true; + +// Parsed as instantiation expression + +const x3 = f; +>x3 : Symbol(x3, Decl(instantiationExpressionErrors.ts, 27, 5)) +>f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) + +true; + diff --git a/tests/baselines/reference/instantiationExpressionErrors.types b/tests/baselines/reference/instantiationExpressionErrors.types new file mode 100644 index 0000000000000..c40d02411d0ba --- /dev/null +++ b/tests/baselines/reference/instantiationExpressionErrors.types @@ -0,0 +1,82 @@ +=== tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts === +declare let f: any; +>f : any + +// Type arguments only permitted at end of member expression + +const a1 = f; +>a1 : any +>f : any + +const a2 = f.g; +>a2 : any +>f.g : any +>f : any +>g : any + +const a3 = f.g; +>a3 : any +>f : any +>g : any + +const a4 = f.g; +>a4 : any +>f : any +>g : any +> : number +> : any + +// Type arguments must follow ?. token + +const b1 = f?.; +>b1 : any +>f?. : any +>f : any + +const b2 = f?.(); +>b2 : any +>f?.() : any +>f : any + +const b3 = f?.(); +>b3 : boolean +>f?.() : boolean +>ff : any +>number : any +>?.() : any +> : any + +// Parsed as function call, even though this differs from JavaScript + +const x1 = f +>x1 : any +>f(true) : any +>f : any +>true : true + +(true); +>true : true + +// Parsed as relational expression + +const x2 = f +>x2 : boolean +>ftrue : boolean +>ff : any +>true : true + +true; +>true : true + +// Parsed as instantiation expression + +const x3 = f; +>x3 : any +>f : any +>true : true + +true; +>true : true + diff --git a/tests/baselines/reference/instantiationExpressions.errors.txt b/tests/baselines/reference/instantiationExpressions.errors.txt new file mode 100644 index 0000000000000..ce226634706b3 --- /dev/null +++ b/tests/baselines/reference/instantiationExpressions.errors.txt @@ -0,0 +1,177 @@ +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts(6,16): error TS1099: Type argument list cannot be empty. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts(9,17): error TS2635: Type '{ (x: T): T; (x: T, n: number): T; (t: [T, U]): [T, U]; }' has no signatures for which the type argument list is applicable. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts(12,21): error TS1099: Type argument list cannot be empty. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts(15,22): error TS2635: Type '{ (x: T): T; (x: T, n: number): T; (t: [T, U]): [T, U]; }' has no signatures for which the type argument list is applicable. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts(18,21): error TS1099: Type argument list cannot be empty. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts(20,22): error TS2635: Type 'ArrayConstructor' has no signatures for which the type argument list is applicable. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts(23,24): error TS1099: Type argument list cannot be empty. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts(25,25): error TS2635: Type 'ArrayConstructor' has no signatures for which the type argument list is applicable. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts(50,16): error TS2635: Type '{ x: string; y: string; }' has no signatures for which the type argument list is applicable. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts(82,16): error TS2635: Type '{ x: string; } & { y: string; }' has no signatures for which the type argument list is applicable. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts(106,16): error TS2635: Type '(a: string, b: number) => string[]' has no signatures for which the type argument list is applicable. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts(114,16): error TS2635: Type '{ x: string; } | { y: string; }' has no signatures for which the type argument list is applicable. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts(126,16): error TS2635: Type '(a: string, b: number) => string[]' has no signatures for which the type argument list is applicable. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts(130,16): error TS2635: Type 'new (a: string, b: number) => string[]' has no signatures for which the type argument list is applicable. + + +==== tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts (14 errors) ==== + declare function fx(x: T): T; + declare function fx(x: T, n: number): T; + declare function fx(t: [T, U]): [T, U]; + + function f1() { + let f0 = fx<>; // Error + ~~ +!!! error TS1099: Type argument list cannot be empty. + let f1 = fx; // { (x: string): string; (x: string, n: number): string; } + let f2 = fx; // (t: [string, number]) => [string, number] + let f3 = fx; // Error + ~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2635: Type '{ (x: T): T; (x: T, n: number): T; (t: [T, U]): [T, U]; }' has no signatures for which the type argument list is applicable. + } + + type T10 = typeof fx<>; // Error + ~~ +!!! error TS1099: Type argument list cannot be empty. + type T11 = typeof fx; // { (x: string): string; (x: string, n: number): string; } + type T12 = typeof fx; // (t: [string, number]) => [string, number] + type T13 = typeof fx; // Error + ~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2635: Type '{ (x: T): T; (x: T, n: number): T; (t: [T, U]): [T, U]; }' has no signatures for which the type argument list is applicable. + + function f2() { + const A0 = Array<>; // Error + ~~ +!!! error TS1099: Type argument list cannot be empty. + const A1 = Array; // new (...) => string[] + const A2 = Array; // Error + ~~~~~~~~~~~~~~ +!!! error TS2635: Type 'ArrayConstructor' has no signatures for which the type argument list is applicable. + } + + type T20 = typeof Array<>; // Error + ~~ +!!! error TS1099: Type argument list cannot be empty. + type T21 = typeof Array; // new (...) => string[] + type T22 = typeof Array; // Error + ~~~~~~~~~~~~~~ +!!! error TS2635: Type 'ArrayConstructor' has no signatures for which the type argument list is applicable. + + declare class C { + constructor(x: T); + static f(x: U): U[]; + } + + function f3() { + let c1 = C; // { new (x: string): C; f(x: U): T[]; prototype: C; } + let f1 = C.f; // (x: string) => string[] + } + + function f10(f: { (a: T): T, (a: U, b: number): U[] }) { + let fs = f; // { (a: string): string; (a: string, b: number): string[]; } + } + + function f11(f: { (a: T): T, (a: string, b: number): string[] }) { + let fs = f; // (a: string) => string + } + + function f12(f: { (a: T): T, x: string }) { + let fs = f; // { (a: string): string; x: string; } + } + + function f13(f: { x: string, y: string }) { + let fs = f; // Error, no applicable signatures + ~~~~~~ +!!! error TS2635: Type '{ x: string; y: string; }' has no signatures for which the type argument list is applicable. + } + + function f14(f: { new (a: T): T, new (a: U, b: number): U[] }) { + let fs = f; // { new (a: string): string; new (a: string, b: number): string[]; } + } + + function f15(f: { new (a: T): T, (a: U, b: number): U[] }) { + let fs = f; // { new (a: string): string; (a: string, b: number): string[]; } + } + + function f16(f: { new (a: T): T, (a: string, b: number): string[] }) { + let fs = f; // new (a: string) => string + } + + function f17(f: { (a: T): T, new (a: string, b: number): string[] }) { + let fs = f; // (a: string) => string + } + + function f20(f: ((a: T) => T) & ((a: U, b: number) => U[])) { + let fs = f; // ((a: string) => string) & ((a: string, b: number) => string[]]) + } + + function f21(f: ((a: T) => T) & ((a: string, b: number) => string[])) { + let fs = f; // (a: string) => string + } + + function f22(f: ((a: T) => T) & { x: string }) { + let fs = f; // ((a: string) => string) & { x: string } + } + + function f23(f: { x: string } & { y: string }) { + let fs = f; // Error, no applicable signatures + ~~~~~~ +!!! error TS2635: Type '{ x: string; } & { y: string; }' has no signatures for which the type argument list is applicable. + } + + function f24(f: (new (a: T) => T) & (new (a: U, b: number) => U[])) { + let fs = f; // (new (a: string) => string) & ((a: string, b: number) => string[]]) + } + + function f25(f: (new (a: T) => T) & ((a: U, b: number) => U[])) { + let fs = f; // (new (a: string) => string) & ((a: string, b: number) => string[]]) + } + + function f26(f: (new (a: T) => T) & ((a: string, b: number) => string[])) { + let fs = f; // new (a: string) => string + } + + function f27(f: ((a: T) => T) & (new (a: string, b: number) => string[])) { + let fs = f; // (a: string) => string + } + + function f30(f: ((a: T) => T) | ((a: U, b: number) => U[])) { + let fs = f; // ((a: string) => string) | ((a: string, b: number) => string[]]) + } + + function f31(f: ((a: T) => T) | ((a: string, b: number) => string[])) { + let fs = f; // Error, '(a: string, b: number) => string[]' has no applicable signatures + ~~~~~~ +!!! error TS2635: Type '(a: string, b: number) => string[]' has no signatures for which the type argument list is applicable. + } + + function f32(f: ((a: T) => T) | { x: string }) { + let fs = f; // ((a: string) => string) | { x: string } + } + + function f33(f: { x: string } | { y: string }) { + let fs = f; // Error, no applicable signatures + ~~~~~~ +!!! error TS2635: Type '{ x: string; } | { y: string; }' has no signatures for which the type argument list is applicable. + } + + function f34(f: (new (a: T) => T) | (new (a: U, b: number) => U[])) { + let fs = f; // (new (a: string) => string) | ((a: string, b: number) => string[]]) + } + + function f35(f: (new (a: T) => T) | ((a: U, b: number) => U[])) { + let fs = f; // (new (a: string) => string) | ((a: string, b: number) => string[]]) + } + + function f36(f: (new (a: T) => T) | ((a: string, b: number) => string[])) { + let fs = f; // Error, '(a: string, b: number) => string[]' has no applicable signatures + ~~~~~~ +!!! error TS2635: Type '(a: string, b: number) => string[]' has no signatures for which the type argument list is applicable. + } + + function f37(f: ((a: T) => T) | (new (a: string, b: number) => string[])) { + let fs = f; // Error, 'new (a: string, b: number) => string[]' has no applicable signatures + ~~~~~~ +!!! error TS2635: Type 'new (a: string, b: number) => string[]' has no signatures for which the type argument list is applicable. + } + \ No newline at end of file diff --git a/tests/baselines/reference/instantiationExpressions.js b/tests/baselines/reference/instantiationExpressions.js new file mode 100644 index 0000000000000..096f237f37f28 --- /dev/null +++ b/tests/baselines/reference/instantiationExpressions.js @@ -0,0 +1,303 @@ +//// [instantiationExpressions.ts] +declare function fx(x: T): T; +declare function fx(x: T, n: number): T; +declare function fx(t: [T, U]): [T, U]; + +function f1() { + let f0 = fx<>; // Error + let f1 = fx; // { (x: string): string; (x: string, n: number): string; } + let f2 = fx; // (t: [string, number]) => [string, number] + let f3 = fx; // Error +} + +type T10 = typeof fx<>; // Error +type T11 = typeof fx; // { (x: string): string; (x: string, n: number): string; } +type T12 = typeof fx; // (t: [string, number]) => [string, number] +type T13 = typeof fx; // Error + +function f2() { + const A0 = Array<>; // Error + const A1 = Array; // new (...) => string[] + const A2 = Array; // Error +} + +type T20 = typeof Array<>; // Error +type T21 = typeof Array; // new (...) => string[] +type T22 = typeof Array; // Error + +declare class C { + constructor(x: T); + static f(x: U): U[]; +} + +function f3() { + let c1 = C; // { new (x: string): C; f(x: U): T[]; prototype: C; } + let f1 = C.f; // (x: string) => string[] +} + +function f10(f: { (a: T): T, (a: U, b: number): U[] }) { + let fs = f; // { (a: string): string; (a: string, b: number): string[]; } +} + +function f11(f: { (a: T): T, (a: string, b: number): string[] }) { + let fs = f; // (a: string) => string +} + +function f12(f: { (a: T): T, x: string }) { + let fs = f; // { (a: string): string; x: string; } +} + +function f13(f: { x: string, y: string }) { + let fs = f; // Error, no applicable signatures +} + +function f14(f: { new (a: T): T, new (a: U, b: number): U[] }) { + let fs = f; // { new (a: string): string; new (a: string, b: number): string[]; } +} + +function f15(f: { new (a: T): T, (a: U, b: number): U[] }) { + let fs = f; // { new (a: string): string; (a: string, b: number): string[]; } +} + +function f16(f: { new (a: T): T, (a: string, b: number): string[] }) { + let fs = f; // new (a: string) => string +} + +function f17(f: { (a: T): T, new (a: string, b: number): string[] }) { + let fs = f; // (a: string) => string +} + +function f20(f: ((a: T) => T) & ((a: U, b: number) => U[])) { + let fs = f; // ((a: string) => string) & ((a: string, b: number) => string[]]) +} + +function f21(f: ((a: T) => T) & ((a: string, b: number) => string[])) { + let fs = f; // (a: string) => string +} + +function f22(f: ((a: T) => T) & { x: string }) { + let fs = f; // ((a: string) => string) & { x: string } +} + +function f23(f: { x: string } & { y: string }) { + let fs = f; // Error, no applicable signatures +} + +function f24(f: (new (a: T) => T) & (new (a: U, b: number) => U[])) { + let fs = f; // (new (a: string) => string) & ((a: string, b: number) => string[]]) +} + +function f25(f: (new (a: T) => T) & ((a: U, b: number) => U[])) { + let fs = f; // (new (a: string) => string) & ((a: string, b: number) => string[]]) +} + +function f26(f: (new (a: T) => T) & ((a: string, b: number) => string[])) { + let fs = f; // new (a: string) => string +} + +function f27(f: ((a: T) => T) & (new (a: string, b: number) => string[])) { + let fs = f; // (a: string) => string +} + +function f30(f: ((a: T) => T) | ((a: U, b: number) => U[])) { + let fs = f; // ((a: string) => string) | ((a: string, b: number) => string[]]) +} + +function f31(f: ((a: T) => T) | ((a: string, b: number) => string[])) { + let fs = f; // Error, '(a: string, b: number) => string[]' has no applicable signatures +} + +function f32(f: ((a: T) => T) | { x: string }) { + let fs = f; // ((a: string) => string) | { x: string } +} + +function f33(f: { x: string } | { y: string }) { + let fs = f; // Error, no applicable signatures +} + +function f34(f: (new (a: T) => T) | (new (a: U, b: number) => U[])) { + let fs = f; // (new (a: string) => string) | ((a: string, b: number) => string[]]) +} + +function f35(f: (new (a: T) => T) | ((a: U, b: number) => U[])) { + let fs = f; // (new (a: string) => string) | ((a: string, b: number) => string[]]) +} + +function f36(f: (new (a: T) => T) | ((a: string, b: number) => string[])) { + let fs = f; // Error, '(a: string, b: number) => string[]' has no applicable signatures +} + +function f37(f: ((a: T) => T) | (new (a: string, b: number) => string[])) { + let fs = f; // Error, 'new (a: string, b: number) => string[]' has no applicable signatures +} + + +//// [instantiationExpressions.js] +"use strict"; +function f1() { + var f0 = fx; // Error + var f1 = (fx); // { (x: string): string; (x: string, n: number): string; } + var f2 = (fx); // (t: [string, number]) => [string, number] + var f3 = (fx); // Error +} +function f2() { + var A0 = Array; // Error + var A1 = (Array); // new (...) => string[] + var A2 = (Array); // Error +} +function f3() { + var c1 = (C); // { new (x: string): C; f(x: U): T[]; prototype: C; } + var f1 = (C.f); // (x: string) => string[] +} +function f10(f) { + var fs = (f); // { (a: string): string; (a: string, b: number): string[]; } +} +function f11(f) { + var fs = (f); // (a: string) => string +} +function f12(f) { + var fs = (f); // { (a: string): string; x: string; } +} +function f13(f) { + var fs = (f); // Error, no applicable signatures +} +function f14(f) { + var fs = (f); // { new (a: string): string; new (a: string, b: number): string[]; } +} +function f15(f) { + var fs = (f); // { new (a: string): string; (a: string, b: number): string[]; } +} +function f16(f) { + var fs = (f); // new (a: string) => string +} +function f17(f) { + var fs = (f); // (a: string) => string +} +function f20(f) { + var fs = (f); // ((a: string) => string) & ((a: string, b: number) => string[]]) +} +function f21(f) { + var fs = (f); // (a: string) => string +} +function f22(f) { + var fs = (f); // ((a: string) => string) & { x: string } +} +function f23(f) { + var fs = (f); // Error, no applicable signatures +} +function f24(f) { + var fs = (f); // (new (a: string) => string) & ((a: string, b: number) => string[]]) +} +function f25(f) { + var fs = (f); // (new (a: string) => string) & ((a: string, b: number) => string[]]) +} +function f26(f) { + var fs = (f); // new (a: string) => string +} +function f27(f) { + var fs = (f); // (a: string) => string +} +function f30(f) { + var fs = (f); // ((a: string) => string) | ((a: string, b: number) => string[]]) +} +function f31(f) { + var fs = (f); // Error, '(a: string, b: number) => string[]' has no applicable signatures +} +function f32(f) { + var fs = (f); // ((a: string) => string) | { x: string } +} +function f33(f) { + var fs = (f); // Error, no applicable signatures +} +function f34(f) { + var fs = (f); // (new (a: string) => string) | ((a: string, b: number) => string[]]) +} +function f35(f) { + var fs = (f); // (new (a: string) => string) | ((a: string, b: number) => string[]]) +} +function f36(f) { + var fs = (f); // Error, '(a: string, b: number) => string[]' has no applicable signatures +} +function f37(f) { + var fs = (f); // Error, 'new (a: string, b: number) => string[]' has no applicable signatures +} + + +//// [instantiationExpressions.d.ts] +declare function fx(x: T): T; +declare function fx(x: T, n: number): T; +declare function fx(t: [T, U]): [T, U]; +declare function f1(): void; +declare type T10 = typeof fx; +declare type T11 = typeof fx; +declare type T12 = typeof fx; +declare type T13 = typeof fx; +declare function f2(): void; +declare type T20 = typeof Array; +declare type T21 = typeof Array; +declare type T22 = typeof Array; +declare class C { + constructor(x: T); + static f(x: U): U[]; +} +declare function f3(): void; +declare function f10(f: { + (a: T): T; + (a: U, b: number): U[]; +}): void; +declare function f11(f: { + (a: T): T; + (a: string, b: number): string[]; +}): void; +declare function f12(f: { + (a: T): T; + x: string; +}): void; +declare function f13(f: { + x: string; + y: string; +}): void; +declare function f14(f: { + new (a: T): T; + new (a: U, b: number): U[]; +}): void; +declare function f15(f: { + new (a: T): T; + (a: U, b: number): U[]; +}): void; +declare function f16(f: { + new (a: T): T; + (a: string, b: number): string[]; +}): void; +declare function f17(f: { + (a: T): T; + new (a: string, b: number): string[]; +}): void; +declare function f20(f: ((a: T) => T) & ((a: U, b: number) => U[])): void; +declare function f21(f: ((a: T) => T) & ((a: string, b: number) => string[])): void; +declare function f22(f: ((a: T) => T) & { + x: string; +}): void; +declare function f23(f: { + x: string; +} & { + y: string; +}): void; +declare function f24(f: (new (a: T) => T) & (new (a: U, b: number) => U[])): void; +declare function f25(f: (new (a: T) => T) & ((a: U, b: number) => U[])): void; +declare function f26(f: (new (a: T) => T) & ((a: string, b: number) => string[])): void; +declare function f27(f: ((a: T) => T) & (new (a: string, b: number) => string[])): void; +declare function f30(f: ((a: T) => T) | ((a: U, b: number) => U[])): void; +declare function f31(f: ((a: T) => T) | ((a: string, b: number) => string[])): void; +declare function f32(f: ((a: T) => T) | { + x: string; +}): void; +declare function f33(f: { + x: string; +} | { + y: string; +}): void; +declare function f34(f: (new (a: T) => T) | (new (a: U, b: number) => U[])): void; +declare function f35(f: (new (a: T) => T) | ((a: U, b: number) => U[])): void; +declare function f36(f: (new (a: T) => T) | ((a: string, b: number) => string[])): void; +declare function f37(f: ((a: T) => T) | (new (a: string, b: number) => string[])): void; diff --git a/tests/baselines/reference/instantiationExpressions.symbols b/tests/baselines/reference/instantiationExpressions.symbols new file mode 100644 index 0000000000000..1a761e06983d8 --- /dev/null +++ b/tests/baselines/reference/instantiationExpressions.symbols @@ -0,0 +1,492 @@ +=== tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts === +declare function fx(x: T): T; +>fx : Symbol(fx, Decl(instantiationExpressions.ts, 0, 0), Decl(instantiationExpressions.ts, 0, 32), Decl(instantiationExpressions.ts, 1, 43)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 0, 20)) +>x : Symbol(x, Decl(instantiationExpressions.ts, 0, 23)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 0, 20)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 0, 20)) + +declare function fx(x: T, n: number): T; +>fx : Symbol(fx, Decl(instantiationExpressions.ts, 0, 0), Decl(instantiationExpressions.ts, 0, 32), Decl(instantiationExpressions.ts, 1, 43)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 1, 20)) +>x : Symbol(x, Decl(instantiationExpressions.ts, 1, 23)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 1, 20)) +>n : Symbol(n, Decl(instantiationExpressions.ts, 1, 28)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 1, 20)) + +declare function fx(t: [T, U]): [T, U]; +>fx : Symbol(fx, Decl(instantiationExpressions.ts, 0, 0), Decl(instantiationExpressions.ts, 0, 32), Decl(instantiationExpressions.ts, 1, 43)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 2, 20)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 2, 22)) +>t : Symbol(t, Decl(instantiationExpressions.ts, 2, 26)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 2, 20)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 2, 22)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 2, 20)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 2, 22)) + +function f1() { +>f1 : Symbol(f1, Decl(instantiationExpressions.ts, 2, 45)) + + let f0 = fx<>; // Error +>f0 : Symbol(f0, Decl(instantiationExpressions.ts, 5, 7)) +>fx : Symbol(fx, Decl(instantiationExpressions.ts, 0, 0), Decl(instantiationExpressions.ts, 0, 32), Decl(instantiationExpressions.ts, 1, 43)) + + let f1 = fx; // { (x: string): string; (x: string, n: number): string; } +>f1 : Symbol(f1, Decl(instantiationExpressions.ts, 6, 7)) +>fx : Symbol(fx, Decl(instantiationExpressions.ts, 0, 0), Decl(instantiationExpressions.ts, 0, 32), Decl(instantiationExpressions.ts, 1, 43)) + + let f2 = fx; // (t: [string, number]) => [string, number] +>f2 : Symbol(f2, Decl(instantiationExpressions.ts, 7, 7)) +>fx : Symbol(fx, Decl(instantiationExpressions.ts, 0, 0), Decl(instantiationExpressions.ts, 0, 32), Decl(instantiationExpressions.ts, 1, 43)) + + let f3 = fx; // Error +>f3 : Symbol(f3, Decl(instantiationExpressions.ts, 8, 7)) +>fx : Symbol(fx, Decl(instantiationExpressions.ts, 0, 0), Decl(instantiationExpressions.ts, 0, 32), Decl(instantiationExpressions.ts, 1, 43)) +} + +type T10 = typeof fx<>; // Error +>T10 : Symbol(T10, Decl(instantiationExpressions.ts, 9, 1)) +>fx : Symbol(fx, Decl(instantiationExpressions.ts, 0, 0), Decl(instantiationExpressions.ts, 0, 32), Decl(instantiationExpressions.ts, 1, 43)) + +type T11 = typeof fx; // { (x: string): string; (x: string, n: number): string; } +>T11 : Symbol(T11, Decl(instantiationExpressions.ts, 11, 23)) +>fx : Symbol(fx, Decl(instantiationExpressions.ts, 0, 0), Decl(instantiationExpressions.ts, 0, 32), Decl(instantiationExpressions.ts, 1, 43)) + +type T12 = typeof fx; // (t: [string, number]) => [string, number] +>T12 : Symbol(T12, Decl(instantiationExpressions.ts, 12, 29)) +>fx : Symbol(fx, Decl(instantiationExpressions.ts, 0, 0), Decl(instantiationExpressions.ts, 0, 32), Decl(instantiationExpressions.ts, 1, 43)) + +type T13 = typeof fx; // Error +>T13 : Symbol(T13, Decl(instantiationExpressions.ts, 13, 37)) +>fx : Symbol(fx, Decl(instantiationExpressions.ts, 0, 0), Decl(instantiationExpressions.ts, 0, 32), Decl(instantiationExpressions.ts, 1, 43)) + +function f2() { +>f2 : Symbol(f2, Decl(instantiationExpressions.ts, 14, 46)) + + const A0 = Array<>; // Error +>A0 : Symbol(A0, Decl(instantiationExpressions.ts, 17, 9)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + + const A1 = Array; // new (...) => string[] +>A1 : Symbol(A1, Decl(instantiationExpressions.ts, 18, 9)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + + const A2 = Array; // Error +>A2 : Symbol(A2, Decl(instantiationExpressions.ts, 19, 9)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +} + +type T20 = typeof Array<>; // Error +>T20 : Symbol(T20, Decl(instantiationExpressions.ts, 20, 1)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + +type T21 = typeof Array; // new (...) => string[] +>T21 : Symbol(T21, Decl(instantiationExpressions.ts, 22, 26)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + +type T22 = typeof Array; // Error +>T22 : Symbol(T22, Decl(instantiationExpressions.ts, 23, 32)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + +declare class C { +>C : Symbol(C, Decl(instantiationExpressions.ts, 24, 40)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 26, 16)) + + constructor(x: T); +>x : Symbol(x, Decl(instantiationExpressions.ts, 27, 16)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 26, 16)) + + static f(x: U): U[]; +>f : Symbol(C.f, Decl(instantiationExpressions.ts, 27, 22)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 28, 13)) +>x : Symbol(x, Decl(instantiationExpressions.ts, 28, 16)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 28, 13)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 28, 13)) +} + +function f3() { +>f3 : Symbol(f3, Decl(instantiationExpressions.ts, 29, 1)) + + let c1 = C; // { new (x: string): C; f(x: U): T[]; prototype: C; } +>c1 : Symbol(c1, Decl(instantiationExpressions.ts, 32, 7)) +>C : Symbol(C, Decl(instantiationExpressions.ts, 24, 40)) + + let f1 = C.f; // (x: string) => string[] +>f1 : Symbol(f1, Decl(instantiationExpressions.ts, 33, 7)) +>C.f : Symbol(C.f, Decl(instantiationExpressions.ts, 27, 22)) +>C : Symbol(C, Decl(instantiationExpressions.ts, 24, 40)) +>f : Symbol(C.f, Decl(instantiationExpressions.ts, 27, 22)) +} + +function f10(f: { (a: T): T, (a: U, b: number): U[] }) { +>f10 : Symbol(f10, Decl(instantiationExpressions.ts, 34, 1)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 36, 13)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 36, 19)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 36, 22)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 36, 19)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 36, 19)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 36, 33)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 36, 36)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 36, 33)) +>b : Symbol(b, Decl(instantiationExpressions.ts, 36, 41)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 36, 33)) + + let fs = f; // { (a: string): string; (a: string, b: number): string[]; } +>fs : Symbol(fs, Decl(instantiationExpressions.ts, 37, 7)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 36, 13)) +} + +function f11(f: { (a: T): T, (a: string, b: number): string[] }) { +>f11 : Symbol(f11, Decl(instantiationExpressions.ts, 38, 1)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 40, 13)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 40, 19)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 40, 22)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 40, 19)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 40, 19)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 40, 33)) +>b : Symbol(b, Decl(instantiationExpressions.ts, 40, 43)) + + let fs = f; // (a: string) => string +>fs : Symbol(fs, Decl(instantiationExpressions.ts, 41, 7)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 40, 13)) +} + +function f12(f: { (a: T): T, x: string }) { +>f12 : Symbol(f12, Decl(instantiationExpressions.ts, 42, 1)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 44, 13)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 44, 19)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 44, 22)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 44, 19)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 44, 19)) +>x : Symbol(x, Decl(instantiationExpressions.ts, 44, 31)) + + let fs = f; // { (a: string): string; x: string; } +>fs : Symbol(fs, Decl(instantiationExpressions.ts, 45, 7)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 44, 13)) +} + +function f13(f: { x: string, y: string }) { +>f13 : Symbol(f13, Decl(instantiationExpressions.ts, 46, 1)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 48, 13)) +>x : Symbol(x, Decl(instantiationExpressions.ts, 48, 17)) +>y : Symbol(y, Decl(instantiationExpressions.ts, 48, 28)) + + let fs = f; // Error, no applicable signatures +>fs : Symbol(fs, Decl(instantiationExpressions.ts, 49, 7)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 48, 13)) +} + +function f14(f: { new (a: T): T, new (a: U, b: number): U[] }) { +>f14 : Symbol(f14, Decl(instantiationExpressions.ts, 50, 1)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 52, 13)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 52, 23)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 52, 26)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 52, 23)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 52, 23)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 52, 41)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 52, 44)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 52, 41)) +>b : Symbol(b, Decl(instantiationExpressions.ts, 52, 49)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 52, 41)) + + let fs = f; // { new (a: string): string; new (a: string, b: number): string[]; } +>fs : Symbol(fs, Decl(instantiationExpressions.ts, 53, 7)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 52, 13)) +} + +function f15(f: { new (a: T): T, (a: U, b: number): U[] }) { +>f15 : Symbol(f15, Decl(instantiationExpressions.ts, 54, 1)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 56, 13)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 56, 23)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 56, 26)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 56, 23)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 56, 23)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 56, 37)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 56, 40)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 56, 37)) +>b : Symbol(b, Decl(instantiationExpressions.ts, 56, 45)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 56, 37)) + + let fs = f; // { new (a: string): string; (a: string, b: number): string[]; } +>fs : Symbol(fs, Decl(instantiationExpressions.ts, 57, 7)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 56, 13)) +} + +function f16(f: { new (a: T): T, (a: string, b: number): string[] }) { +>f16 : Symbol(f16, Decl(instantiationExpressions.ts, 58, 1)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 60, 13)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 60, 23)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 60, 26)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 60, 23)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 60, 23)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 60, 37)) +>b : Symbol(b, Decl(instantiationExpressions.ts, 60, 47)) + + let fs = f; // new (a: string) => string +>fs : Symbol(fs, Decl(instantiationExpressions.ts, 61, 7)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 60, 13)) +} + +function f17(f: { (a: T): T, new (a: string, b: number): string[] }) { +>f17 : Symbol(f17, Decl(instantiationExpressions.ts, 62, 1)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 64, 13)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 64, 19)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 64, 22)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 64, 19)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 64, 19)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 64, 37)) +>b : Symbol(b, Decl(instantiationExpressions.ts, 64, 47)) + + let fs = f; // (a: string) => string +>fs : Symbol(fs, Decl(instantiationExpressions.ts, 65, 7)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 64, 13)) +} + +function f20(f: ((a: T) => T) & ((a: U, b: number) => U[])) { +>f20 : Symbol(f20, Decl(instantiationExpressions.ts, 66, 1)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 68, 13)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 68, 18)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 68, 21)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 68, 18)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 68, 18)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 68, 37)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 68, 40)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 68, 37)) +>b : Symbol(b, Decl(instantiationExpressions.ts, 68, 45)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 68, 37)) + + let fs = f; // ((a: string) => string) & ((a: string, b: number) => string[]]) +>fs : Symbol(fs, Decl(instantiationExpressions.ts, 69, 7)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 68, 13)) +} + +function f21(f: ((a: T) => T) & ((a: string, b: number) => string[])) { +>f21 : Symbol(f21, Decl(instantiationExpressions.ts, 70, 1)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 72, 13)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 72, 18)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 72, 21)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 72, 18)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 72, 18)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 72, 37)) +>b : Symbol(b, Decl(instantiationExpressions.ts, 72, 47)) + + let fs = f; // (a: string) => string +>fs : Symbol(fs, Decl(instantiationExpressions.ts, 73, 7)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 72, 13)) +} + +function f22(f: ((a: T) => T) & { x: string }) { +>f22 : Symbol(f22, Decl(instantiationExpressions.ts, 74, 1)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 76, 13)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 76, 18)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 76, 21)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 76, 18)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 76, 18)) +>x : Symbol(x, Decl(instantiationExpressions.ts, 76, 36)) + + let fs = f; // ((a: string) => string) & { x: string } +>fs : Symbol(fs, Decl(instantiationExpressions.ts, 77, 7)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 76, 13)) +} + +function f23(f: { x: string } & { y: string }) { +>f23 : Symbol(f23, Decl(instantiationExpressions.ts, 78, 1)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 80, 13)) +>x : Symbol(x, Decl(instantiationExpressions.ts, 80, 17)) +>y : Symbol(y, Decl(instantiationExpressions.ts, 80, 33)) + + let fs = f; // Error, no applicable signatures +>fs : Symbol(fs, Decl(instantiationExpressions.ts, 81, 7)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 80, 13)) +} + +function f24(f: (new (a: T) => T) & (new (a: U, b: number) => U[])) { +>f24 : Symbol(f24, Decl(instantiationExpressions.ts, 82, 1)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 84, 13)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 84, 22)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 84, 25)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 84, 22)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 84, 22)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 84, 45)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 84, 48)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 84, 45)) +>b : Symbol(b, Decl(instantiationExpressions.ts, 84, 53)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 84, 45)) + + let fs = f; // (new (a: string) => string) & ((a: string, b: number) => string[]]) +>fs : Symbol(fs, Decl(instantiationExpressions.ts, 85, 7)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 84, 13)) +} + +function f25(f: (new (a: T) => T) & ((a: U, b: number) => U[])) { +>f25 : Symbol(f25, Decl(instantiationExpressions.ts, 86, 1)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 88, 13)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 88, 22)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 88, 25)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 88, 22)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 88, 22)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 88, 41)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 88, 44)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 88, 41)) +>b : Symbol(b, Decl(instantiationExpressions.ts, 88, 49)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 88, 41)) + + let fs = f; // (new (a: string) => string) & ((a: string, b: number) => string[]]) +>fs : Symbol(fs, Decl(instantiationExpressions.ts, 89, 7)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 88, 13)) +} + +function f26(f: (new (a: T) => T) & ((a: string, b: number) => string[])) { +>f26 : Symbol(f26, Decl(instantiationExpressions.ts, 90, 1)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 92, 13)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 92, 22)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 92, 25)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 92, 22)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 92, 22)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 92, 41)) +>b : Symbol(b, Decl(instantiationExpressions.ts, 92, 51)) + + let fs = f; // new (a: string) => string +>fs : Symbol(fs, Decl(instantiationExpressions.ts, 93, 7)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 92, 13)) +} + +function f27(f: ((a: T) => T) & (new (a: string, b: number) => string[])) { +>f27 : Symbol(f27, Decl(instantiationExpressions.ts, 94, 1)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 96, 13)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 96, 18)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 96, 21)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 96, 18)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 96, 18)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 96, 41)) +>b : Symbol(b, Decl(instantiationExpressions.ts, 96, 51)) + + let fs = f; // (a: string) => string +>fs : Symbol(fs, Decl(instantiationExpressions.ts, 97, 7)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 96, 13)) +} + +function f30(f: ((a: T) => T) | ((a: U, b: number) => U[])) { +>f30 : Symbol(f30, Decl(instantiationExpressions.ts, 98, 1)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 100, 13)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 100, 18)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 100, 21)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 100, 18)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 100, 18)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 100, 37)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 100, 40)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 100, 37)) +>b : Symbol(b, Decl(instantiationExpressions.ts, 100, 45)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 100, 37)) + + let fs = f; // ((a: string) => string) | ((a: string, b: number) => string[]]) +>fs : Symbol(fs, Decl(instantiationExpressions.ts, 101, 7)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 100, 13)) +} + +function f31(f: ((a: T) => T) | ((a: string, b: number) => string[])) { +>f31 : Symbol(f31, Decl(instantiationExpressions.ts, 102, 1)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 104, 13)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 104, 18)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 104, 21)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 104, 18)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 104, 18)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 104, 37)) +>b : Symbol(b, Decl(instantiationExpressions.ts, 104, 47)) + + let fs = f; // Error, '(a: string, b: number) => string[]' has no applicable signatures +>fs : Symbol(fs, Decl(instantiationExpressions.ts, 105, 7)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 104, 13)) +} + +function f32(f: ((a: T) => T) | { x: string }) { +>f32 : Symbol(f32, Decl(instantiationExpressions.ts, 106, 1)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 108, 13)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 108, 18)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 108, 21)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 108, 18)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 108, 18)) +>x : Symbol(x, Decl(instantiationExpressions.ts, 108, 36)) + + let fs = f; // ((a: string) => string) | { x: string } +>fs : Symbol(fs, Decl(instantiationExpressions.ts, 109, 7)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 108, 13)) +} + +function f33(f: { x: string } | { y: string }) { +>f33 : Symbol(f33, Decl(instantiationExpressions.ts, 110, 1)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 112, 13)) +>x : Symbol(x, Decl(instantiationExpressions.ts, 112, 17)) +>y : Symbol(y, Decl(instantiationExpressions.ts, 112, 33)) + + let fs = f; // Error, no applicable signatures +>fs : Symbol(fs, Decl(instantiationExpressions.ts, 113, 7)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 112, 13)) +} + +function f34(f: (new (a: T) => T) | (new (a: U, b: number) => U[])) { +>f34 : Symbol(f34, Decl(instantiationExpressions.ts, 114, 1)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 116, 13)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 116, 22)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 116, 25)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 116, 22)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 116, 22)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 116, 45)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 116, 48)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 116, 45)) +>b : Symbol(b, Decl(instantiationExpressions.ts, 116, 53)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 116, 45)) + + let fs = f; // (new (a: string) => string) | ((a: string, b: number) => string[]]) +>fs : Symbol(fs, Decl(instantiationExpressions.ts, 117, 7)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 116, 13)) +} + +function f35(f: (new (a: T) => T) | ((a: U, b: number) => U[])) { +>f35 : Symbol(f35, Decl(instantiationExpressions.ts, 118, 1)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 120, 13)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 120, 22)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 120, 25)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 120, 22)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 120, 22)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 120, 41)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 120, 44)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 120, 41)) +>b : Symbol(b, Decl(instantiationExpressions.ts, 120, 49)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 120, 41)) + + let fs = f; // (new (a: string) => string) | ((a: string, b: number) => string[]]) +>fs : Symbol(fs, Decl(instantiationExpressions.ts, 121, 7)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 120, 13)) +} + +function f36(f: (new (a: T) => T) | ((a: string, b: number) => string[])) { +>f36 : Symbol(f36, Decl(instantiationExpressions.ts, 122, 1)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 124, 13)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 124, 22)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 124, 25)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 124, 22)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 124, 22)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 124, 41)) +>b : Symbol(b, Decl(instantiationExpressions.ts, 124, 51)) + + let fs = f; // Error, '(a: string, b: number) => string[]' has no applicable signatures +>fs : Symbol(fs, Decl(instantiationExpressions.ts, 125, 7)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 124, 13)) +} + +function f37(f: ((a: T) => T) | (new (a: string, b: number) => string[])) { +>f37 : Symbol(f37, Decl(instantiationExpressions.ts, 126, 1)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 128, 13)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 128, 18)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 128, 21)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 128, 18)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 128, 18)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 128, 41)) +>b : Symbol(b, Decl(instantiationExpressions.ts, 128, 51)) + + let fs = f; // Error, 'new (a: string, b: number) => string[]' has no applicable signatures +>fs : Symbol(fs, Decl(instantiationExpressions.ts, 129, 7)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 128, 13)) +} + diff --git a/tests/baselines/reference/instantiationExpressions.types b/tests/baselines/reference/instantiationExpressions.types new file mode 100644 index 0000000000000..2529607bc4863 --- /dev/null +++ b/tests/baselines/reference/instantiationExpressions.types @@ -0,0 +1,385 @@ +=== tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts === +declare function fx(x: T): T; +>fx : { (x: T): T; (x: T, n: number): T; (t: [T, U]): [T, U]; } +>x : T + +declare function fx(x: T, n: number): T; +>fx : { (x: T): T; (x: T, n: number): T; (t: [T, U]): [T, U]; } +>x : T +>n : number + +declare function fx(t: [T, U]): [T, U]; +>fx : { (x: T): T; (x: T, n: number): T; (t: [T, U]): [T, U]; } +>t : [T, U] + +function f1() { +>f1 : () => void + + let f0 = fx<>; // Error +>f0 : { (x: T): T; (x: T, n: number): T; (t: [T, U]): [T, U]; } +>fx : { (x: T): T; (x: T, n: number): T; (t: [T, U]): [T, U]; } + + let f1 = fx; // { (x: string): string; (x: string, n: number): string; } +>f1 : { (x: string): string; (x: string, n: number): string; } +>fx : { (x: T): T; (x: T, n: number): T; (t: [T, U]): [T, U]; } + + let f2 = fx; // (t: [string, number]) => [string, number] +>f2 : (t: [string, number]) => [string, number] +>fx : { (x: T): T; (x: T, n: number): T; (t: [T, U]): [T, U]; } + + let f3 = fx; // Error +>f3 : {} +>fx : { (x: T): T; (x: T, n: number): T; (t: [T, U]): [T, U]; } +} + +type T10 = typeof fx<>; // Error +>T10 : { (x: T): T; (x: T, n: number): T; (t: [T, U]): [T, U]; } +>fx : { (x: T): T; (x: T, n: number): T; (t: [T, U]): [T, U]; } + +type T11 = typeof fx; // { (x: string): string; (x: string, n: number): string; } +>T11 : { (x: string): string; (x: string, n: number): string; } +>fx : { (x: T): T; (x: T, n: number): T; (t: [T, U]): [T, U]; } + +type T12 = typeof fx; // (t: [string, number]) => [string, number] +>T12 : (t: [string, number]) => [string, number] +>fx : { (x: T): T; (x: T, n: number): T; (t: [T, U]): [T, U]; } + +type T13 = typeof fx; // Error +>T13 : {} +>fx : { (x: T): T; (x: T, n: number): T; (t: [T, U]): [T, U]; } + +function f2() { +>f2 : () => void + + const A0 = Array<>; // Error +>A0 : ArrayConstructor +>Array : ArrayConstructor + + const A1 = Array; // new (...) => string[] +>A1 : { (arrayLength: number): string[]; (...items: string[]): string[]; new (arrayLength: number): string[]; new (...items: string[]): string[]; isArray(arg: any): arg is any[]; readonly prototype: any[]; } +>Array : ArrayConstructor + + const A2 = Array; // Error +>A2 : { isArray(arg: any): arg is any[]; readonly prototype: any[]; } +>Array : ArrayConstructor +} + +type T20 = typeof Array<>; // Error +>T20 : ArrayConstructor +>Array : ArrayConstructor + +type T21 = typeof Array; // new (...) => string[] +>T21 : { (arrayLength: number): string[]; (...items: string[]): string[]; new (arrayLength: number): string[]; new (...items: string[]): string[]; isArray(arg: any): arg is any[]; readonly prototype: any[]; } +>Array : ArrayConstructor + +type T22 = typeof Array; // Error +>T22 : { isArray(arg: any): arg is any[]; readonly prototype: any[]; } +>Array : ArrayConstructor + +declare class C { +>C : C + + constructor(x: T); +>x : T + + static f(x: U): U[]; +>f : (x: U) => U[] +>x : U +} + +function f3() { +>f3 : () => void + + let c1 = C; // { new (x: string): C; f(x: U): T[]; prototype: C; } +>c1 : { new (x: string): C; prototype: C; f(x: U): U[]; } +>C : typeof C + + let f1 = C.f; // (x: string) => string[] +>f1 : (x: string) => string[] +>C.f : (x: U) => U[] +>C : typeof C +>f : (x: U) => U[] +} + +function f10(f: { (a: T): T, (a: U, b: number): U[] }) { +>f10 : (f: { (a: T): T; (a: U, b: number): U[]; }) => void +>f : { (a: T): T; (a: U, b: number): U[]; } +>a : T +>a : U +>b : number + + let fs = f; // { (a: string): string; (a: string, b: number): string[]; } +>fs : { (a: string): string; (a: string, b: number): string[]; } +>f : { (a: T): T; (a: U, b: number): U[]; } +} + +function f11(f: { (a: T): T, (a: string, b: number): string[] }) { +>f11 : (f: { (a: T): T; (a: string, b: number): string[]; }) => void +>f : { (a: T): T; (a: string, b: number): string[]; } +>a : T +>a : string +>b : number + + let fs = f; // (a: string) => string +>fs : (a: string) => string +>f : { (a: T): T; (a: string, b: number): string[]; } +} + +function f12(f: { (a: T): T, x: string }) { +>f12 : (f: { (a: T): T; x: string; }) => void +>f : { (a: T): T; x: string; } +>a : T +>x : string + + let fs = f; // { (a: string): string; x: string; } +>fs : { (a: string): string; x: string; } +>f : { (a: T): T; x: string; } +} + +function f13(f: { x: string, y: string }) { +>f13 : (f: { x: string; y: string;}) => void +>f : { x: string; y: string; } +>x : string +>y : string + + let fs = f; // Error, no applicable signatures +>fs : { x: string; y: string; } +>f : { x: string; y: string; } +} + +function f14(f: { new (a: T): T, new (a: U, b: number): U[] }) { +>f14 : (f: { new (a: T): T; new (a: U, b: number): U[]; }) => void +>f : { new (a: T): T; new (a: U, b: number): U[]; } +>a : T +>a : U +>b : number + + let fs = f; // { new (a: string): string; new (a: string, b: number): string[]; } +>fs : { new (a: string): string; new (a: string, b: number): string[]; } +>f : { new (a: T): T; new (a: U, b: number): U[]; } +} + +function f15(f: { new (a: T): T, (a: U, b: number): U[] }) { +>f15 : (f: { (a: U, b: number): U[]; new (a: T): T; }) => void +>f : { (a: U, b: number): U[]; new (a: T): T; } +>a : T +>a : U +>b : number + + let fs = f; // { new (a: string): string; (a: string, b: number): string[]; } +>fs : { (a: string, b: number): string[]; new (a: string): string; } +>f : { (a: U, b: number): U[]; new (a: T): T; } +} + +function f16(f: { new (a: T): T, (a: string, b: number): string[] }) { +>f16 : (f: { (a: string, b: number): string[]; new (a: T): T; }) => void +>f : { (a: string, b: number): string[]; new (a: T): T; } +>a : T +>a : string +>b : number + + let fs = f; // new (a: string) => string +>fs : new (a: string) => string +>f : { (a: string, b: number): string[]; new (a: T): T; } +} + +function f17(f: { (a: T): T, new (a: string, b: number): string[] }) { +>f17 : (f: { (a: T): T; new (a: string, b: number): string[]; }) => void +>f : { (a: T): T; new (a: string, b: number): string[]; } +>a : T +>a : string +>b : number + + let fs = f; // (a: string) => string +>fs : (a: string) => string +>f : { (a: T): T; new (a: string, b: number): string[]; } +} + +function f20(f: ((a: T) => T) & ((a: U, b: number) => U[])) { +>f20 : (f: ((a: T) => T) & ((a: U, b: number) => U[])) => void +>f : ((a: T) => T) & ((a: U, b: number) => U[]) +>a : T +>a : U +>b : number + + let fs = f; // ((a: string) => string) & ((a: string, b: number) => string[]]) +>fs : ((a: string) => string) & ((a: string, b: number) => string[]) +>f : ((a: T) => T) & ((a: U, b: number) => U[]) +} + +function f21(f: ((a: T) => T) & ((a: string, b: number) => string[])) { +>f21 : (f: ((a: T) => T) & ((a: string, b: number) => string[])) => void +>f : ((a: T) => T) & ((a: string, b: number) => string[]) +>a : T +>a : string +>b : number + + let fs = f; // (a: string) => string +>fs : (a: string) => string +>f : ((a: T) => T) & ((a: string, b: number) => string[]) +} + +function f22(f: ((a: T) => T) & { x: string }) { +>f22 : (f: ((a: T) => T) & { x: string; }) => void +>f : ((a: T) => T) & { x: string; } +>a : T +>x : string + + let fs = f; // ((a: string) => string) & { x: string } +>fs : ((a: string) => string) & { x: string; } +>f : ((a: T) => T) & { x: string; } +} + +function f23(f: { x: string } & { y: string }) { +>f23 : (f: { x: string;} & { y: string;}) => void +>f : { x: string; } & { y: string; } +>x : string +>y : string + + let fs = f; // Error, no applicable signatures +>fs : { x: string; } & { y: string; } +>f : { x: string; } & { y: string; } +} + +function f24(f: (new (a: T) => T) & (new (a: U, b: number) => U[])) { +>f24 : (f: (new (a: T) => T) & (new (a: U, b: number) => U[])) => void +>f : (new (a: T) => T) & (new (a: U, b: number) => U[]) +>a : T +>a : U +>b : number + + let fs = f; // (new (a: string) => string) & ((a: string, b: number) => string[]]) +>fs : (new (a: string) => string) & (new (a: string, b: number) => string[]) +>f : (new (a: T) => T) & (new (a: U, b: number) => U[]) +} + +function f25(f: (new (a: T) => T) & ((a: U, b: number) => U[])) { +>f25 : (f: (new (a: T) => T) & ((a: U, b: number) => U[])) => void +>f : (new (a: T) => T) & ((a: U, b: number) => U[]) +>a : T +>a : U +>b : number + + let fs = f; // (new (a: string) => string) & ((a: string, b: number) => string[]]) +>fs : (new (a: string) => string) & ((a: string, b: number) => string[]) +>f : (new (a: T) => T) & ((a: U, b: number) => U[]) +} + +function f26(f: (new (a: T) => T) & ((a: string, b: number) => string[])) { +>f26 : (f: (new (a: T) => T) & ((a: string, b: number) => string[])) => void +>f : (new (a: T) => T) & ((a: string, b: number) => string[]) +>a : T +>a : string +>b : number + + let fs = f; // new (a: string) => string +>fs : new (a: string) => string +>f : (new (a: T) => T) & ((a: string, b: number) => string[]) +} + +function f27(f: ((a: T) => T) & (new (a: string, b: number) => string[])) { +>f27 : (f: ((a: T) => T) & (new (a: string, b: number) => string[])) => void +>f : ((a: T) => T) & (new (a: string, b: number) => string[]) +>a : T +>a : string +>b : number + + let fs = f; // (a: string) => string +>fs : (a: string) => string +>f : ((a: T) => T) & (new (a: string, b: number) => string[]) +} + +function f30(f: ((a: T) => T) | ((a: U, b: number) => U[])) { +>f30 : (f: ((a: T) => T) | ((a: U, b: number) => U[])) => void +>f : ((a: T) => T) | ((a: U, b: number) => U[]) +>a : T +>a : U +>b : number + + let fs = f; // ((a: string) => string) | ((a: string, b: number) => string[]]) +>fs : ((a: string) => string) | ((a: string, b: number) => string[]) +>f : ((a: T) => T) | ((a: U, b: number) => U[]) +} + +function f31(f: ((a: T) => T) | ((a: string, b: number) => string[])) { +>f31 : (f: ((a: T) => T) | ((a: string, b: number) => string[])) => void +>f : ((a: T) => T) | ((a: string, b: number) => string[]) +>a : T +>a : string +>b : number + + let fs = f; // Error, '(a: string, b: number) => string[]' has no applicable signatures +>fs : ((a: string) => string) | {} +>f : ((a: T) => T) | ((a: string, b: number) => string[]) +} + +function f32(f: ((a: T) => T) | { x: string }) { +>f32 : (f: { x: string; } | ((a: T) => T)) => void +>f : { x: string; } | ((a: T) => T) +>a : T +>x : string + + let fs = f; // ((a: string) => string) | { x: string } +>fs : { x: string; } | ((a: string) => string) +>f : { x: string; } | ((a: T) => T) +} + +function f33(f: { x: string } | { y: string }) { +>f33 : (f: { x: string;} | { y: string;}) => void +>f : { x: string; } | { y: string; } +>x : string +>y : string + + let fs = f; // Error, no applicable signatures +>fs : { x: string; } | { y: string; } +>f : { x: string; } | { y: string; } +} + +function f34(f: (new (a: T) => T) | (new (a: U, b: number) => U[])) { +>f34 : (f: (new (a: T) => T) | (new (a: U, b: number) => U[])) => void +>f : (new (a: T) => T) | (new (a: U, b: number) => U[]) +>a : T +>a : U +>b : number + + let fs = f; // (new (a: string) => string) | ((a: string, b: number) => string[]]) +>fs : (new (a: string) => string) | (new (a: string, b: number) => string[]) +>f : (new (a: T) => T) | (new (a: U, b: number) => U[]) +} + +function f35(f: (new (a: T) => T) | ((a: U, b: number) => U[])) { +>f35 : (f: (new (a: T) => T) | ((a: U, b: number) => U[])) => void +>f : (new (a: T) => T) | ((a: U, b: number) => U[]) +>a : T +>a : U +>b : number + + let fs = f; // (new (a: string) => string) | ((a: string, b: number) => string[]]) +>fs : (new (a: string) => string) | ((a: string, b: number) => string[]) +>f : (new (a: T) => T) | ((a: U, b: number) => U[]) +} + +function f36(f: (new (a: T) => T) | ((a: string, b: number) => string[])) { +>f36 : (f: (new (a: T) => T) | ((a: string, b: number) => string[])) => void +>f : (new (a: T) => T) | ((a: string, b: number) => string[]) +>a : T +>a : string +>b : number + + let fs = f; // Error, '(a: string, b: number) => string[]' has no applicable signatures +>fs : (new (a: string) => string) | {} +>f : (new (a: T) => T) | ((a: string, b: number) => string[]) +} + +function f37(f: ((a: T) => T) | (new (a: string, b: number) => string[])) { +>f37 : (f: ((a: T) => T) | (new (a: string, b: number) => string[])) => void +>f : ((a: T) => T) | (new (a: string, b: number) => string[]) +>a : T +>a : string +>b : number + + let fs = f; // Error, 'new (a: string, b: number) => string[]' has no applicable signatures +>fs : ((a: string) => string) | {} +>f : ((a: T) => T) | (new (a: string, b: number) => string[]) +} + From aaf4d12015f0d418d32e2c11f8fe3d9e0694c510 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 26 Jan 2022 17:16:55 -0800 Subject: [PATCH 08/16] Properly handle instantiation of instantiation expression types --- src/compiler/checker.ts | 146 +++++++++++++++++++++------------------- src/compiler/types.ts | 12 +++- 2 files changed, 85 insertions(+), 73 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9114d1cf72cae..02dcaf12fb169 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -753,7 +753,6 @@ namespace ts { const templateLiteralTypes = new Map(); const stringMappingTypes = new Map(); const substitutionTypes = new Map(); - const instantiatedFunctionTypes = new Map(); const subtypeReductionCache = new Map(); const evolvingArrayTypes: EvolvingArrayType[] = []; const undefinedProperties: SymbolTable = new Map(); @@ -11256,7 +11255,6 @@ namespace ts { * Converts an AnonymousType to a ResolvedType. */ function resolveAnonymousTypeMembers(type: AnonymousType) { - const symbol = getMergedSymbol(type.symbol); if (type.target) { setStructuredTypeMembers(type, emptySymbols, emptyArray, emptyArray, emptyArray); const members = createInstantiatedSymbolTable(getPropertiesOfObjectType(type.target), type.mapper!, /*mappingThisOnly*/ false); @@ -11264,82 +11262,83 @@ namespace ts { const constructSignatures = instantiateSignatures(getSignaturesOfType(type.target, SignatureKind.Construct), type.mapper!); const indexInfos = instantiateIndexInfos(getIndexInfosOfType(type.target), type.mapper!); setStructuredTypeMembers(type, members, callSignatures, constructSignatures, indexInfos); + return; } - else if (symbol.flags & SymbolFlags.TypeLiteral) { + const symbol = getMergedSymbol(type.symbol); + if (symbol.flags & SymbolFlags.TypeLiteral) { setStructuredTypeMembers(type, emptySymbols, emptyArray, emptyArray, emptyArray); const members = getMembersOfSymbol(symbol); const callSignatures = getSignaturesOfSymbol(members.get(InternalSymbolName.Call)); const constructSignatures = getSignaturesOfSymbol(members.get(InternalSymbolName.New)); const indexInfos = getIndexInfosOfSymbol(symbol); setStructuredTypeMembers(type, members, callSignatures, constructSignatures, indexInfos); + return; } - else { - // Combinations of function, class, enum and module - let members = emptySymbols; - let indexInfos: IndexInfo[] | undefined; - if (symbol.exports) { - members = getExportsOfSymbol(symbol); - if (symbol === globalThisSymbol) { - const varsOnly = new Map() as SymbolTable; - members.forEach(p => { - if (!(p.flags & SymbolFlags.BlockScoped)) { - varsOnly.set(p.escapedName, p); - } - }); - members = varsOnly; - } + // Combinations of function, class, enum and module + let members = emptySymbols; + let indexInfos: IndexInfo[] | undefined; + if (symbol.exports) { + members = getExportsOfSymbol(symbol); + if (symbol === globalThisSymbol) { + const varsOnly = new Map() as SymbolTable; + members.forEach(p => { + if (!(p.flags & SymbolFlags.BlockScoped)) { + varsOnly.set(p.escapedName, p); + } + }); + members = varsOnly; } - let baseConstructorIndexInfo: IndexInfo | undefined; - setStructuredTypeMembers(type, members, emptyArray, emptyArray, emptyArray); - if (symbol.flags & SymbolFlags.Class) { - const classType = getDeclaredTypeOfClassOrInterface(symbol); - const baseConstructorType = getBaseConstructorTypeOfClass(classType); - if (baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection | TypeFlags.TypeVariable)) { - members = createSymbolTable(getNamedOrIndexSignatureMembers(members)); - addInheritedMembers(members, getPropertiesOfType(baseConstructorType)); - } - else if (baseConstructorType === anyType) { - baseConstructorIndexInfo = createIndexInfo(stringType, anyType, /*isReadonly*/ false); - } + } + let baseConstructorIndexInfo: IndexInfo | undefined; + setStructuredTypeMembers(type, members, emptyArray, emptyArray, emptyArray); + if (symbol.flags & SymbolFlags.Class) { + const classType = getDeclaredTypeOfClassOrInterface(symbol); + const baseConstructorType = getBaseConstructorTypeOfClass(classType); + if (baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection | TypeFlags.TypeVariable)) { + members = createSymbolTable(getNamedOrIndexSignatureMembers(members)); + addInheritedMembers(members, getPropertiesOfType(baseConstructorType)); + } + else if (baseConstructorType === anyType) { + baseConstructorIndexInfo = createIndexInfo(stringType, anyType, /*isReadonly*/ false); } + } - const indexSymbol = getIndexSymbolFromSymbolTable(members); - if (indexSymbol) { - indexInfos = getIndexInfosOfIndexSymbol(indexSymbol); + const indexSymbol = getIndexSymbolFromSymbolTable(members); + if (indexSymbol) { + indexInfos = getIndexInfosOfIndexSymbol(indexSymbol); + } + else { + if (baseConstructorIndexInfo) { + indexInfos = append(indexInfos, baseConstructorIndexInfo); } - else { - if (baseConstructorIndexInfo) { - indexInfos = append(indexInfos, baseConstructorIndexInfo); - } - if (symbol.flags & SymbolFlags.Enum && (getDeclaredTypeOfSymbol(symbol).flags & TypeFlags.Enum || - some(type.properties, prop => !!(getTypeOfSymbol(prop).flags & TypeFlags.NumberLike)))) { - indexInfos = append(indexInfos, enumNumberIndexInfo); - } + if (symbol.flags & SymbolFlags.Enum && (getDeclaredTypeOfSymbol(symbol).flags & TypeFlags.Enum || + some(type.properties, prop => !!(getTypeOfSymbol(prop).flags & TypeFlags.NumberLike)))) { + indexInfos = append(indexInfos, enumNumberIndexInfo); } - setStructuredTypeMembers(type, members, emptyArray, emptyArray, indexInfos || emptyArray); - // We resolve the members before computing the signatures because a signature may use - // typeof with a qualified name expression that circularly references the type we are - // in the process of resolving (see issue #6072). The temporarily empty signature list - // will never be observed because a qualified name can't reference signatures. - if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Method)) { - type.callSignatures = getSignaturesOfSymbol(symbol); + } + setStructuredTypeMembers(type, members, emptyArray, emptyArray, indexInfos || emptyArray); + // We resolve the members before computing the signatures because a signature may use + // typeof with a qualified name expression that circularly references the type we are + // in the process of resolving (see issue #6072). The temporarily empty signature list + // will never be observed because a qualified name can't reference signatures. + if (symbol.flags & (SymbolFlags.Function | SymbolFlags.Method)) { + type.callSignatures = getSignaturesOfSymbol(symbol); + } + // And likewise for construct signatures for classes + if (symbol.flags & SymbolFlags.Class) { + const classType = getDeclaredTypeOfClassOrInterface(symbol); + let constructSignatures = symbol.members ? getSignaturesOfSymbol(symbol.members.get(InternalSymbolName.Constructor)) : emptyArray; + if (symbol.flags & SymbolFlags.Function) { + constructSignatures = addRange(constructSignatures.slice(), mapDefined( + type.callSignatures, + sig => isJSConstructor(sig.declaration) ? + createSignature(sig.declaration, sig.typeParameters, sig.thisParameter, sig.parameters, classType, /*resolvedTypePredicate*/ undefined, sig.minArgumentCount, sig.flags & SignatureFlags.PropagatingFlags) : + undefined)); } - // And likewise for construct signatures for classes - if (symbol.flags & SymbolFlags.Class) { - const classType = getDeclaredTypeOfClassOrInterface(symbol); - let constructSignatures = symbol.members ? getSignaturesOfSymbol(symbol.members.get(InternalSymbolName.Constructor)) : emptyArray; - if (symbol.flags & SymbolFlags.Function) { - constructSignatures = addRange(constructSignatures.slice(), mapDefined( - type.callSignatures, - sig => isJSConstructor(sig.declaration) ? - createSignature(sig.declaration, sig.typeParameters, sig.thisParameter, sig.parameters, classType, /*resolvedTypePredicate*/ undefined, sig.minArgumentCount, sig.flags & SignatureFlags.PropagatingFlags) : - undefined)); - } - if (!constructSignatures.length) { - constructSignatures = getDefaultConstructSignatures(classType); - } - type.constructSignatures = constructSignatures; + if (!constructSignatures.length) { + constructSignatures = getDefaultConstructSignatures(classType); } + type.constructSignatures = constructSignatures; } } @@ -16544,7 +16543,9 @@ namespace ts { } function getObjectTypeInstantiation(type: AnonymousType | DeferredTypeReference, mapper: TypeMapper, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]) { - const declaration = type.objectFlags & ObjectFlags.Reference ? (type as TypeReference).node! : type.symbol.declarations![0]; + const declaration = type.objectFlags & ObjectFlags.Reference ? (type as TypeReference).node! : + type.objectFlags & ObjectFlags.InstantiationExpressionType ? (type as InstantiationExpressionType).node! : + type.symbol.declarations![0]; const links = getNodeLinks(declaration); const target = type.objectFlags & ObjectFlags.Reference ? links.resolvedType! as DeferredTypeReference : type.objectFlags & ObjectFlags.Instantiated ? type.target! : type; @@ -16560,8 +16561,8 @@ namespace ts { outerTypeParameters = addRange(outerTypeParameters, templateTagParameters); } typeParameters = outerTypeParameters || emptyArray; - const allDeclarations = type.objectFlags & ObjectFlags.Reference ? [declaration] : type.symbol.declarations!; - typeParameters = (target.objectFlags & ObjectFlags.Reference || target.symbol.flags & SymbolFlags.Method || target.symbol.flags & SymbolFlags.TypeLiteral) && !target.aliasTypeArguments ? + const allDeclarations = type.objectFlags & (ObjectFlags.Reference | ObjectFlags.InstantiationExpressionType) ? [declaration] : type.symbol.declarations!; + typeParameters = (target.objectFlags & (ObjectFlags.Reference | ObjectFlags.InstantiationExpressionType) || target.symbol.flags & SymbolFlags.Method || target.symbol.flags & SymbolFlags.TypeLiteral) && !target.aliasTypeArguments ? filter(typeParameters, tp => some(allDeclarations, d => isTypeParameterPossiblyReferenced(tp, d))) : typeParameters; links.outerTypeParameters = typeParameters; @@ -16742,6 +16743,9 @@ namespace ts { mapper = combineTypeMappers(makeUnaryTypeMapper(origTypeParameter, freshTypeParameter), mapper); freshTypeParameter.mapper = mapper; } + if (type.objectFlags & ObjectFlags.InstantiationExpressionType) { + (result as InstantiationExpressionType).node = (type as InstantiationExpressionType).node; + } result.target = type; result.mapper = mapper; result.aliasSymbol = aliasSymbol || type.aliasSymbol; @@ -21475,7 +21479,7 @@ namespace ts { type.flags & TypeFlags.Object && !isNonGenericTopLevelType(type) && ( objectFlags & ObjectFlags.Reference && ((type as TypeReference).node || forEach(getTypeArguments(type as TypeReference), couldContainTypeVariables)) || objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral) && type.symbol.declarations || - objectFlags & (ObjectFlags.Mapped | ObjectFlags.ReverseMapped | ObjectFlags.ObjectRestType)) || + objectFlags & (ObjectFlags.Mapped | ObjectFlags.ReverseMapped | ObjectFlags.ObjectRestType | ObjectFlags.InstantiationExpressionType)) || type.flags & TypeFlags.UnionOrIntersection && !(type.flags & TypeFlags.EnumLiteral) && !isNonGenericTopLevelType(type) && some((type as UnionOrIntersectionType).types, couldContainTypeVariables)); if (type.flags & TypeFlags.ObjectFlagsType) { (type as ObjectFlagsType).objectFlags |= ObjectFlags.CouldContainTypeVariablesComputed | (result ? ObjectFlags.CouldContainTypeVariables : 0); @@ -31422,8 +31426,7 @@ namespace ts { if (errorType) { diagnostics.add(createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.Type_0_has_no_signatures_for_which_the_type_argument_list_is_applicable, typeToString(errorType))); } - const key = `${getTypeId(exprType)},${getTypeListId(map(typeArguments, getTypeFromTypeNode))}`; - return instantiatedFunctionTypes.get(key) || (instantiatedFunctionTypes.set(key, result), result); + return result; function getInstantiatedType(type: Type): Type { hasSignatures = false; @@ -31444,7 +31447,10 @@ namespace ts { hasSignatures ||= resolved.callSignatures.length !== 0 || resolved.constructSignatures.length !== 0; hasApplicableSignature ||= callSignatures.length !== 0 || constructSignatures.length !== 0; if (callSignatures !== resolved.callSignatures || constructSignatures !== resolved.constructSignatures) { - return createAnonymousType(undefined, resolved.members, callSignatures, constructSignatures, resolved.indexInfos); + const result = createAnonymousType(undefined, resolved.members, callSignatures, constructSignatures, resolved.indexInfos) as ResolvedType & InstantiationExpressionType; + result.objectFlags |= ObjectFlags.InstantiationExpressionType; + result.node = node; + return result; } } else if (type.flags & TypeFlags.Intersection) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index cd03599cdea2d..095d25fdae5d9 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5329,13 +5329,14 @@ namespace ts { // Flags that require TypeFlags.Object ContainsSpread = 1 << 22, // Object literal contains spread operation ObjectRestType = 1 << 23, // Originates in object rest declaration + InstantiationExpressionType = 1 << 24, // Originates in instantiation expression /* @internal */ - IsClassInstanceClone = 1 << 24, // Type is a clone of a class instance type + IsClassInstanceClone = 1 << 25, // Type is a clone of a class instance type // Flags that require TypeFlags.Object and ObjectFlags.Reference /* @internal */ - IdenticalBaseTypeCalculated = 1 << 25, // has had `getSingleBaseForNonAugmentingSubtype` invoked on it already + IdenticalBaseTypeCalculated = 1 << 26, // has had `getSingleBaseForNonAugmentingSubtype` invoked on it already /* @internal */ - IdenticalBaseTypeExists = 1 << 26, // has a defined cachedEquivalentBaseType member + IdenticalBaseTypeExists = 1 << 27, // has a defined cachedEquivalentBaseType member // Flags that require TypeFlags.UnionOrIntersection or TypeFlags.Substitution /* @internal */ @@ -5520,6 +5521,11 @@ namespace ts { instantiations?: ESMap; // Instantiations of generic type alias (undefined if non-generic) } + /* @internal */ + export interface InstantiationExpressionType extends AnonymousType { + node: ExpressionWithTypeArguments | TypeQueryNode; + } + /* @internal */ export interface MappedType extends AnonymousType { declaration: MappedTypeNode; From e7ebe5c2668ed86f7ef1285401b06c62fb2f7c0e Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 26 Jan 2022 17:17:09 -0800 Subject: [PATCH 09/16] Accept new API baselines --- tests/baselines/reference/api/tsserverlibrary.d.ts | 1 + tests/baselines/reference/api/typescript.d.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 7f8e8fb8189b2..ad1817c9ea3f0 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2656,6 +2656,7 @@ declare namespace ts { ClassOrInterface = 3, ContainsSpread = 4194304, ObjectRestType = 8388608, + InstantiationExpressionType = 16777216, } export interface ObjectType extends Type { objectFlags: ObjectFlags; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 80c7e5e4b3c8d..11fa7acdabfda 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2656,6 +2656,7 @@ declare namespace ts { ClassOrInterface = 3, ContainsSpread = 4194304, ObjectRestType = 8388608, + InstantiationExpressionType = 16777216, } export interface ObjectType extends Type { objectFlags: ObjectFlags; From 483e8df72d230d4d209d9eb700f860474e91be11 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 26 Jan 2022 17:58:35 -0800 Subject: [PATCH 10/16] Fix lint error --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 02dcaf12fb169..3e9562d47b0ac 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -16544,7 +16544,7 @@ namespace ts { function getObjectTypeInstantiation(type: AnonymousType | DeferredTypeReference, mapper: TypeMapper, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]) { const declaration = type.objectFlags & ObjectFlags.Reference ? (type as TypeReference).node! : - type.objectFlags & ObjectFlags.InstantiationExpressionType ? (type as InstantiationExpressionType).node! : + type.objectFlags & ObjectFlags.InstantiationExpressionType ? (type as InstantiationExpressionType).node : type.symbol.declarations![0]; const links = getNodeLinks(declaration); const target = type.objectFlags & ObjectFlags.Reference ? links.resolvedType! as DeferredTypeReference : From 8e466ba661ba47556ff314268202a4350fca19a5 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 27 Jan 2022 07:36:02 -0800 Subject: [PATCH 11/16] Add more tests --- .../instantiationExpressions.errors.txt | 49 ++++++- .../reference/instantiationExpressions.js | 71 ++++++++++ .../instantiationExpressions.symbols | 133 ++++++++++++++++++ .../reference/instantiationExpressions.types | 85 +++++++++++ .../instantiationExpressions.ts | 37 +++++ 5 files changed, 374 insertions(+), 1 deletion(-) diff --git a/tests/baselines/reference/instantiationExpressions.errors.txt b/tests/baselines/reference/instantiationExpressions.errors.txt index ce226634706b3..39d1ae7c531cc 100644 --- a/tests/baselines/reference/instantiationExpressions.errors.txt +++ b/tests/baselines/reference/instantiationExpressions.errors.txt @@ -12,9 +12,13 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpr tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts(114,16): error TS2635: Type '{ x: string; } | { y: string; }' has no signatures for which the type argument list is applicable. tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts(126,16): error TS2635: Type '(a: string, b: number) => string[]' has no signatures for which the type argument list is applicable. tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts(130,16): error TS2635: Type 'new (a: string, b: number) => string[]' has no signatures for which the type argument list is applicable. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts(159,40): error TS2344: Type 'U' does not satisfy the constraint 'number'. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts(160,40): error TS2344: Type 'U' does not satisfy the constraint 'string'. + Type 'number' is not assignable to type 'string'. -==== tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts (14 errors) ==== +==== tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts (16 errors) ==== declare function fx(x: T): T; declare function fx(x: T, n: number): T; declare function fx(t: [T, U]): [T, U]; @@ -174,4 +178,47 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpr ~~~~~~ !!! error TS2635: Type 'new (a: string, b: number) => string[]' has no signatures for which the type argument list is applicable. } + + function makeBox(value: T) { + return { value }; + } + + type BoxFunc = typeof makeBox; // (value: T) => { value: T } + type StringBoxFunc = BoxFunc; // (value: string) => { value: string } + + type Box = ReturnType>; // { value: T } + type StringBox = Box; // { value: string } + + type A = InstanceType>; // U[] + + declare const g1: { + (a: T): { a: T }; + new (b: U): { b: U }; + } + + type T30 = typeof g1; // { (a: V) => { a: V }; new (b: V) => { b: V }; } + type T31 = ReturnType>; // { a: A } + type T32 = InstanceType>; // { b: B } + + declare const g2: { + (a: T): T; + new (b: T): T; + } + + type T40 = typeof g2; // Error + ~ +!!! error TS2344: Type 'U' does not satisfy the constraint 'number'. +!!! error TS2344: Type 'string' is not assignable to type 'number'. + type T41 = typeof g2; // Error + ~ +!!! error TS2344: Type 'U' does not satisfy the constraint 'string'. +!!! error TS2344: Type 'number' is not assignable to type 'string'. + + declare const g3: { + (a: T): T; + new (b: T): T; + } + + type T50 = typeof g3; // (a: U) => U + type T51 = typeof g3; // (b: U) => U \ No newline at end of file diff --git a/tests/baselines/reference/instantiationExpressions.js b/tests/baselines/reference/instantiationExpressions.js index 096f237f37f28..4774d5116ac7b 100644 --- a/tests/baselines/reference/instantiationExpressions.js +++ b/tests/baselines/reference/instantiationExpressions.js @@ -130,6 +130,43 @@ function f36(f: (new (a: T) => T) | ((a: string, b: number) => string[])) { function f37(f: ((a: T) => T) | (new (a: string, b: number) => string[])) { let fs = f; // Error, 'new (a: string, b: number) => string[]' has no applicable signatures } + +function makeBox(value: T) { + return { value }; +} + +type BoxFunc = typeof makeBox; // (value: T) => { value: T } +type StringBoxFunc = BoxFunc; // (value: string) => { value: string } + +type Box = ReturnType>; // { value: T } +type StringBox = Box; // { value: string } + +type A = InstanceType>; // U[] + +declare const g1: { + (a: T): { a: T }; + new (b: U): { b: U }; +} + +type T30 = typeof g1; // { (a: V) => { a: V }; new (b: V) => { b: V }; } +type T31 = ReturnType>; // { a: A } +type T32 = InstanceType>; // { b: B } + +declare const g2: { + (a: T): T; + new (b: T): T; +} + +type T40 = typeof g2; // Error +type T41 = typeof g2; // Error + +declare const g3: { + (a: T): T; + new (b: T): T; +} + +type T50 = typeof g3; // (a: U) => U +type T51 = typeof g3; // (b: U) => U //// [instantiationExpressions.js] @@ -221,6 +258,9 @@ function f36(f) { function f37(f) { var fs = (f); // Error, 'new (a: string, b: number) => string[]' has no applicable signatures } +function makeBox(value) { + return { value: value }; +} //// [instantiationExpressions.d.ts] @@ -301,3 +341,34 @@ declare function f34(f: (new (a: T) => T) | (new (a: U, b: number) => U[]) declare function f35(f: (new (a: T) => T) | ((a: U, b: number) => U[])): void; declare function f36(f: (new (a: T) => T) | ((a: string, b: number) => string[])): void; declare function f37(f: ((a: T) => T) | (new (a: string, b: number) => string[])): void; +declare function makeBox(value: T): { + value: T; +}; +declare type BoxFunc = typeof makeBox; +declare type StringBoxFunc = BoxFunc; +declare type Box = ReturnType>; +declare type StringBox = Box; +declare type A = InstanceType>; +declare const g1: { + (a: T): { + a: T; + }; + new (b: U): { + b: U; + }; +}; +declare type T30 = typeof g1; +declare type T31 = ReturnType>; +declare type T32 = InstanceType>; +declare const g2: { + (a: T): T; + new (b: T): T; +}; +declare type T40 = typeof g2; +declare type T41 = typeof g2; +declare const g3: { + (a: T): T; + new (b: T): T; +}; +declare type T50 = typeof g3; +declare type T51 = typeof g3; diff --git a/tests/baselines/reference/instantiationExpressions.symbols b/tests/baselines/reference/instantiationExpressions.symbols index 1a761e06983d8..a63932c284fbe 100644 --- a/tests/baselines/reference/instantiationExpressions.symbols +++ b/tests/baselines/reference/instantiationExpressions.symbols @@ -490,3 +490,136 @@ function f37(f: ((a: T) => T) | (new (a: string, b: number) => string[])) { >f : Symbol(f, Decl(instantiationExpressions.ts, 128, 13)) } +function makeBox(value: T) { +>makeBox : Symbol(makeBox, Decl(instantiationExpressions.ts, 130, 1)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 132, 17)) +>value : Symbol(value, Decl(instantiationExpressions.ts, 132, 20)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 132, 17)) + + return { value }; +>value : Symbol(value, Decl(instantiationExpressions.ts, 133, 12)) +} + +type BoxFunc = typeof makeBox; // (value: T) => { value: T } +>BoxFunc : Symbol(BoxFunc, Decl(instantiationExpressions.ts, 134, 1)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 136, 13)) +>makeBox : Symbol(makeBox, Decl(instantiationExpressions.ts, 130, 1)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 136, 13)) + +type StringBoxFunc = BoxFunc; // (value: string) => { value: string } +>StringBoxFunc : Symbol(StringBoxFunc, Decl(instantiationExpressions.ts, 136, 36)) +>BoxFunc : Symbol(BoxFunc, Decl(instantiationExpressions.ts, 134, 1)) + +type Box = ReturnType>; // { value: T } +>Box : Symbol(Box, Decl(instantiationExpressions.ts, 137, 37)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 139, 9)) +>ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) +>makeBox : Symbol(makeBox, Decl(instantiationExpressions.ts, 130, 1)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 139, 9)) + +type StringBox = Box; // { value: string } +>StringBox : Symbol(StringBox, Decl(instantiationExpressions.ts, 139, 44)) +>Box : Symbol(Box, Decl(instantiationExpressions.ts, 137, 37)) + +type A = InstanceType>; // U[] +>A : Symbol(A, Decl(instantiationExpressions.ts, 140, 29)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 142, 7)) +>InstanceType : Symbol(InstanceType, Decl(lib.es5.d.ts, --, --)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 142, 7)) + +declare const g1: { +>g1 : Symbol(g1, Decl(instantiationExpressions.ts, 144, 13)) + + (a: T): { a: T }; +>T : Symbol(T, Decl(instantiationExpressions.ts, 145, 5)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 145, 8)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 145, 5)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 145, 16)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 145, 5)) + + new (b: U): { b: U }; +>U : Symbol(U, Decl(instantiationExpressions.ts, 146, 9)) +>b : Symbol(b, Decl(instantiationExpressions.ts, 146, 12)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 146, 9)) +>b : Symbol(b, Decl(instantiationExpressions.ts, 146, 20)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 146, 9)) +} + +type T30 = typeof g1; // { (a: V) => { a: V }; new (b: V) => { b: V }; } +>T30 : Symbol(T30, Decl(instantiationExpressions.ts, 147, 1)) +>V : Symbol(V, Decl(instantiationExpressions.ts, 149, 9)) +>g1 : Symbol(g1, Decl(instantiationExpressions.ts, 144, 13)) +>V : Symbol(V, Decl(instantiationExpressions.ts, 149, 9)) + +type T31 = ReturnType>; // { a: A } +>T31 : Symbol(T31, Decl(instantiationExpressions.ts, 149, 27)) +>A : Symbol(A, Decl(instantiationExpressions.ts, 150, 9)) +>ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) +>T30 : Symbol(T30, Decl(instantiationExpressions.ts, 147, 1)) +>A : Symbol(A, Decl(instantiationExpressions.ts, 150, 9)) + +type T32 = InstanceType>; // { b: B } +>T32 : Symbol(T32, Decl(instantiationExpressions.ts, 150, 33)) +>B : Symbol(B, Decl(instantiationExpressions.ts, 151, 9)) +>InstanceType : Symbol(InstanceType, Decl(lib.es5.d.ts, --, --)) +>T30 : Symbol(T30, Decl(instantiationExpressions.ts, 147, 1)) +>B : Symbol(B, Decl(instantiationExpressions.ts, 151, 9)) + +declare const g2: { +>g2 : Symbol(g2, Decl(instantiationExpressions.ts, 153, 13)) + + (a: T): T; +>T : Symbol(T, Decl(instantiationExpressions.ts, 154, 5)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 154, 23)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 154, 5)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 154, 5)) + + new (b: T): T; +>T : Symbol(T, Decl(instantiationExpressions.ts, 155, 9)) +>b : Symbol(b, Decl(instantiationExpressions.ts, 155, 27)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 155, 9)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 155, 9)) +} + +type T40 = typeof g2; // Error +>T40 : Symbol(T40, Decl(instantiationExpressions.ts, 156, 1)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 158, 9)) +>g2 : Symbol(g2, Decl(instantiationExpressions.ts, 153, 13)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 158, 9)) + +type T41 = typeof g2; // Error +>T41 : Symbol(T41, Decl(instantiationExpressions.ts, 158, 42)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 159, 9)) +>g2 : Symbol(g2, Decl(instantiationExpressions.ts, 153, 13)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 159, 9)) + +declare const g3: { +>g3 : Symbol(g3, Decl(instantiationExpressions.ts, 161, 13)) + + (a: T): T; +>T : Symbol(T, Decl(instantiationExpressions.ts, 162, 5)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 162, 23)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 162, 5)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 162, 5)) + + new (b: T): T; +>T : Symbol(T, Decl(instantiationExpressions.ts, 163, 9)) +>Q : Symbol(Q, Decl(instantiationExpressions.ts, 163, 26)) +>b : Symbol(b, Decl(instantiationExpressions.ts, 163, 30)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 163, 9)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 163, 9)) +} + +type T50 = typeof g3; // (a: U) => U +>T50 : Symbol(T50, Decl(instantiationExpressions.ts, 164, 1)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 166, 9)) +>g3 : Symbol(g3, Decl(instantiationExpressions.ts, 161, 13)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 166, 9)) + +type T51 = typeof g3; // (b: U) => U +>T51 : Symbol(T51, Decl(instantiationExpressions.ts, 166, 42)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 167, 9)) +>g3 : Symbol(g3, Decl(instantiationExpressions.ts, 161, 13)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 167, 9)) + diff --git a/tests/baselines/reference/instantiationExpressions.types b/tests/baselines/reference/instantiationExpressions.types index 2529607bc4863..8a14081739ab1 100644 --- a/tests/baselines/reference/instantiationExpressions.types +++ b/tests/baselines/reference/instantiationExpressions.types @@ -383,3 +383,88 @@ function f37(f: ((a: T) => T) | (new (a: string, b: number) => string[])) { >f : ((a: T) => T) | (new (a: string, b: number) => string[]) } +function makeBox(value: T) { +>makeBox : (value: T) => { value: T; } +>value : T + + return { value }; +>{ value } : { value: T; } +>value : T +} + +type BoxFunc = typeof makeBox; // (value: T) => { value: T } +>BoxFunc : (value: T) => { value: T; } +>makeBox : (value: T) => { value: T; } + +type StringBoxFunc = BoxFunc; // (value: string) => { value: string } +>StringBoxFunc : StringBoxFunc + +type Box = ReturnType>; // { value: T } +>Box : { value: T; } +>makeBox : (value: T) => { value: T; } + +type StringBox = Box; // { value: string } +>StringBox : StringBox + +type A = InstanceType>; // U[] +>A : U[] +>Array : ArrayConstructor + +declare const g1: { +>g1 : { (a: T): { a: T; }; new (b: U): { b: U; }; } + + (a: T): { a: T }; +>a : T +>a : T + + new (b: U): { b: U }; +>b : U +>b : U +} + +type T30 = typeof g1; // { (a: V) => { a: V }; new (b: V) => { b: V }; } +>T30 : { (a: V): { a: V; }; new (b: V): { b: V; }; } +>g1 : { (a: T): { a: T; }; new (b: U): { b: U; }; } + +type T31 = ReturnType>; // { a: A } +>T31 : { a: A; } + +type T32 = InstanceType>; // { b: B } +>T32 : { b: B; } + +declare const g2: { +>g2 : { (a: T): T; new (b: T): T; } + + (a: T): T; +>a : T + + new (b: T): T; +>b : T +} + +type T40 = typeof g2; // Error +>T40 : { (a: U): U; new (b: T): T; } +>g2 : { (a: T): T; new (b: T): T; } + +type T41 = typeof g2; // Error +>T41 : { (a: T): T; new (b: U): U; } +>g2 : { (a: T): T; new (b: T): T; } + +declare const g3: { +>g3 : { (a: T): T; new (b: T): T; } + + (a: T): T; +>a : T + + new (b: T): T; +>b : T +} + +type T50 = typeof g3; // (a: U) => U +>T50 : (a: U) => U +>g3 : { (a: T): T; new (b: T): T; } + +type T51 = typeof g3; // (b: U) => U +>T51 : new (b: U) => U +>g3 : { (a: T): T; new (b: T): T; } + diff --git a/tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts b/tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts index 793cbf765b17e..00e375c8836d0 100644 --- a/tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts +++ b/tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts @@ -132,3 +132,40 @@ function f36(f: (new (a: T) => T) | ((a: string, b: number) => string[])) { function f37(f: ((a: T) => T) | (new (a: string, b: number) => string[])) { let fs = f; // Error, 'new (a: string, b: number) => string[]' has no applicable signatures } + +function makeBox(value: T) { + return { value }; +} + +type BoxFunc = typeof makeBox; // (value: T) => { value: T } +type StringBoxFunc = BoxFunc; // (value: string) => { value: string } + +type Box = ReturnType>; // { value: T } +type StringBox = Box; // { value: string } + +type A = InstanceType>; // U[] + +declare const g1: { + (a: T): { a: T }; + new (b: U): { b: U }; +} + +type T30 = typeof g1; // { (a: V) => { a: V }; new (b: V) => { b: V }; } +type T31 = ReturnType>; // { a: A } +type T32 = InstanceType>; // { b: B } + +declare const g2: { + (a: T): T; + new (b: T): T; +} + +type T40 = typeof g2; // Error +type T41 = typeof g2; // Error + +declare const g3: { + (a: T): T; + new (b: T): T; +} + +type T50 = typeof g3; // (a: U) => U +type T51 = typeof g3; // (b: U) => U From 387bf3a58bd119e31f7ecf54e56c181b8852a94c Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 28 Jan 2022 16:05:15 -0800 Subject: [PATCH 12/16] Properly handle unions/intersections of generic types --- src/compiler/checker.ts | 64 ++++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3e9562d47b0ac..b1bb99696f163 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -31410,53 +31410,59 @@ namespace ts { isThisIdentifier(node.exprName) ? checkThisExpression(node.exprName) : checkExpression(node.exprName); const typeArguments = node.typeArguments; - if (!some(typeArguments)) { + if (exprType === silentNeverType || isErrorType(exprType) || !some(typeArguments)) { return exprType; } - const funcType = getApparentType(exprType); - if (funcType === silentNeverType || isErrorType(funcType)) { - return funcType; - } let hasSomeApplicableSignature = false; let nonApplicableType: Type | undefined; - let hasSignatures: boolean; - let hasApplicableSignature: boolean; - const result = mapType(funcType, getInstantiatedType); - const errorType = hasSomeApplicableSignature ? nonApplicableType : funcType; + const result = getInstantiatedType(exprType); + const errorType = hasSomeApplicableSignature ? nonApplicableType : exprType; if (errorType) { diagnostics.add(createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.Type_0_has_no_signatures_for_which_the_type_argument_list_is_applicable, typeToString(errorType))); } return result; function getInstantiatedType(type: Type): Type { - hasSignatures = false; - hasApplicableSignature = false; - const result = getInstantiatedTypeWorker(type); + let hasSignatures = false; + let hasApplicableSignature = false; + const result = getInstantiatedTypePart(type); hasSomeApplicableSignature ||= hasApplicableSignature; if (hasSignatures && !hasApplicableSignature) { nonApplicableType ??= type; } return result; - } - function getInstantiatedTypeWorker(type: Type): Type { - if (type.flags & TypeFlags.Object) { - const resolved = resolveStructuredTypeMembers(type as ObjectType); - const callSignatures = getInstantiatedSignatures(resolved.callSignatures); - const constructSignatures = getInstantiatedSignatures(resolved.constructSignatures); - hasSignatures ||= resolved.callSignatures.length !== 0 || resolved.constructSignatures.length !== 0; - hasApplicableSignature ||= callSignatures.length !== 0 || constructSignatures.length !== 0; - if (callSignatures !== resolved.callSignatures || constructSignatures !== resolved.constructSignatures) { - const result = createAnonymousType(undefined, resolved.members, callSignatures, constructSignatures, resolved.indexInfos) as ResolvedType & InstantiationExpressionType; - result.objectFlags |= ObjectFlags.InstantiationExpressionType; - result.node = node; - return result; + function getInstantiatedTypePart(type: Type): Type { + if (type.flags & TypeFlags.Object) { + const resolved = resolveStructuredTypeMembers(type as ObjectType); + const callSignatures = getInstantiatedSignatures(resolved.callSignatures); + const constructSignatures = getInstantiatedSignatures(resolved.constructSignatures); + hasSignatures ||= resolved.callSignatures.length !== 0 || resolved.constructSignatures.length !== 0; + hasApplicableSignature ||= callSignatures.length !== 0 || constructSignatures.length !== 0; + if (callSignatures !== resolved.callSignatures || constructSignatures !== resolved.constructSignatures) { + const result = createAnonymousType(undefined, resolved.members, callSignatures, constructSignatures, resolved.indexInfos) as ResolvedType & InstantiationExpressionType; + result.objectFlags |= ObjectFlags.InstantiationExpressionType; + result.node = node; + return result; + } } + else if (type.flags & TypeFlags.InstantiableNonPrimitive) { + const constraint = getBaseConstraintOfType(type); + if (constraint) { + const instantiated = getInstantiatedTypePart(constraint); + if (instantiated !== constraint) { + return instantiated; + } + } + } + else if (type.flags & TypeFlags.Union) { + return mapType(type, getInstantiatedType); + } + else if (type.flags & TypeFlags.Intersection) { + return getIntersectionType(sameMap((type as IntersectionType).types, getInstantiatedTypePart)); + } + return type; } - else if (type.flags & TypeFlags.Intersection) { - return getIntersectionType(sameMap((type as IntersectionType).types, getInstantiatedTypeWorker)); - } - return type; } function getInstantiatedSignatures(signatures: readonly Signature[]) { From a2d03528c92d7f693b0d213f7a3f44d8a9c11c4b Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 28 Jan 2022 16:18:07 -0800 Subject: [PATCH 13/16] Add more tests --- .../instantiationExpressions.errors.txt | 8 +- .../reference/instantiationExpressions.js | 8 + .../instantiationExpressions.symbols | 181 ++++++++++-------- .../reference/instantiationExpressions.types | 12 ++ .../instantiationExpressions.ts | 4 + 5 files changed, 133 insertions(+), 80 deletions(-) diff --git a/tests/baselines/reference/instantiationExpressions.errors.txt b/tests/baselines/reference/instantiationExpressions.errors.txt index 39d1ae7c531cc..d4af975c75fc2 100644 --- a/tests/baselines/reference/instantiationExpressions.errors.txt +++ b/tests/baselines/reference/instantiationExpressions.errors.txt @@ -12,9 +12,9 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpr tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts(114,16): error TS2635: Type '{ x: string; } | { y: string; }' has no signatures for which the type argument list is applicable. tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts(126,16): error TS2635: Type '(a: string, b: number) => string[]' has no signatures for which the type argument list is applicable. tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts(130,16): error TS2635: Type 'new (a: string, b: number) => string[]' has no signatures for which the type argument list is applicable. -tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts(159,40): error TS2344: Type 'U' does not satisfy the constraint 'number'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts(163,40): error TS2344: Type 'U' does not satisfy the constraint 'number'. Type 'string' is not assignable to type 'number'. -tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts(160,40): error TS2344: Type 'U' does not satisfy the constraint 'string'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts(164,40): error TS2344: Type 'U' does not satisfy the constraint 'string'. Type 'number' is not assignable to type 'string'. @@ -179,6 +179,10 @@ tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpr !!! error TS2635: Type 'new (a: string, b: number) => string[]' has no signatures for which the type argument list is applicable. } + function f38(x: A) => A) | ((x: B) => B[]), U>(f: T | U | ((x: C) => C[][])) { + let fs = f; // U | ((x: string) => string) | ((x: string) => string[]) | ((x: string) => string[][]) + } + function makeBox(value: T) { return { value }; } diff --git a/tests/baselines/reference/instantiationExpressions.js b/tests/baselines/reference/instantiationExpressions.js index 4774d5116ac7b..4d1ec7817d82a 100644 --- a/tests/baselines/reference/instantiationExpressions.js +++ b/tests/baselines/reference/instantiationExpressions.js @@ -131,6 +131,10 @@ function f37(f: ((a: T) => T) | (new (a: string, b: number) => string[])) { let fs = f; // Error, 'new (a: string, b: number) => string[]' has no applicable signatures } +function f38(x: A) => A) | ((x: B) => B[]), U>(f: T | U | ((x: C) => C[][])) { + let fs = f; // U | ((x: string) => string) | ((x: string) => string[]) | ((x: string) => string[][]) +} + function makeBox(value: T) { return { value }; } @@ -258,6 +262,9 @@ function f36(f) { function f37(f) { var fs = (f); // Error, 'new (a: string, b: number) => string[]' has no applicable signatures } +function f38(f) { + var fs = (f); // U | ((x: string) => string) | ((x: string) => string[]) | ((x: string) => string[][]) +} function makeBox(value) { return { value: value }; } @@ -341,6 +348,7 @@ declare function f34(f: (new (a: T) => T) | (new (a: U, b: number) => U[]) declare function f35(f: (new (a: T) => T) | ((a: U, b: number) => U[])): void; declare function f36(f: (new (a: T) => T) | ((a: string, b: number) => string[])): void; declare function f37(f: ((a: T) => T) | (new (a: string, b: number) => string[])): void; +declare function f38(x: A) => A) | ((x: B) => B[]), U>(f: T | U | ((x: C) => C[][])): void; declare function makeBox(value: T): { value: T; }; diff --git a/tests/baselines/reference/instantiationExpressions.symbols b/tests/baselines/reference/instantiationExpressions.symbols index a63932c284fbe..3fd52bf485bc2 100644 --- a/tests/baselines/reference/instantiationExpressions.symbols +++ b/tests/baselines/reference/instantiationExpressions.symbols @@ -490,136 +490,161 @@ function f37(f: ((a: T) => T) | (new (a: string, b: number) => string[])) { >f : Symbol(f, Decl(instantiationExpressions.ts, 128, 13)) } +function f38(x: A) => A) | ((x: B) => B[]), U>(f: T | U | ((x: C) => C[][])) { +>f38 : Symbol(f38, Decl(instantiationExpressions.ts, 130, 1)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 132, 13)) +>A : Symbol(A, Decl(instantiationExpressions.ts, 132, 25)) +>x : Symbol(x, Decl(instantiationExpressions.ts, 132, 28)) +>A : Symbol(A, Decl(instantiationExpressions.ts, 132, 25)) +>A : Symbol(A, Decl(instantiationExpressions.ts, 132, 25)) +>B : Symbol(B, Decl(instantiationExpressions.ts, 132, 44)) +>x : Symbol(x, Decl(instantiationExpressions.ts, 132, 47)) +>B : Symbol(B, Decl(instantiationExpressions.ts, 132, 44)) +>B : Symbol(B, Decl(instantiationExpressions.ts, 132, 44)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 132, 61)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 132, 65)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 132, 13)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 132, 61)) +>C : Symbol(C, Decl(instantiationExpressions.ts, 132, 78)) +>x : Symbol(x, Decl(instantiationExpressions.ts, 132, 81)) +>C : Symbol(C, Decl(instantiationExpressions.ts, 132, 78)) +>C : Symbol(C, Decl(instantiationExpressions.ts, 132, 78)) + + let fs = f; // U | ((x: string) => string) | ((x: string) => string[]) | ((x: string) => string[][]) +>fs : Symbol(fs, Decl(instantiationExpressions.ts, 133, 7)) +>f : Symbol(f, Decl(instantiationExpressions.ts, 132, 65)) +} + function makeBox(value: T) { ->makeBox : Symbol(makeBox, Decl(instantiationExpressions.ts, 130, 1)) ->T : Symbol(T, Decl(instantiationExpressions.ts, 132, 17)) ->value : Symbol(value, Decl(instantiationExpressions.ts, 132, 20)) ->T : Symbol(T, Decl(instantiationExpressions.ts, 132, 17)) +>makeBox : Symbol(makeBox, Decl(instantiationExpressions.ts, 134, 1)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 136, 17)) +>value : Symbol(value, Decl(instantiationExpressions.ts, 136, 20)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 136, 17)) return { value }; ->value : Symbol(value, Decl(instantiationExpressions.ts, 133, 12)) +>value : Symbol(value, Decl(instantiationExpressions.ts, 137, 12)) } type BoxFunc = typeof makeBox; // (value: T) => { value: T } ->BoxFunc : Symbol(BoxFunc, Decl(instantiationExpressions.ts, 134, 1)) ->T : Symbol(T, Decl(instantiationExpressions.ts, 136, 13)) ->makeBox : Symbol(makeBox, Decl(instantiationExpressions.ts, 130, 1)) ->T : Symbol(T, Decl(instantiationExpressions.ts, 136, 13)) +>BoxFunc : Symbol(BoxFunc, Decl(instantiationExpressions.ts, 138, 1)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 140, 13)) +>makeBox : Symbol(makeBox, Decl(instantiationExpressions.ts, 134, 1)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 140, 13)) type StringBoxFunc = BoxFunc; // (value: string) => { value: string } ->StringBoxFunc : Symbol(StringBoxFunc, Decl(instantiationExpressions.ts, 136, 36)) ->BoxFunc : Symbol(BoxFunc, Decl(instantiationExpressions.ts, 134, 1)) +>StringBoxFunc : Symbol(StringBoxFunc, Decl(instantiationExpressions.ts, 140, 36)) +>BoxFunc : Symbol(BoxFunc, Decl(instantiationExpressions.ts, 138, 1)) type Box = ReturnType>; // { value: T } ->Box : Symbol(Box, Decl(instantiationExpressions.ts, 137, 37)) ->T : Symbol(T, Decl(instantiationExpressions.ts, 139, 9)) +>Box : Symbol(Box, Decl(instantiationExpressions.ts, 141, 37)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 143, 9)) >ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) ->makeBox : Symbol(makeBox, Decl(instantiationExpressions.ts, 130, 1)) ->T : Symbol(T, Decl(instantiationExpressions.ts, 139, 9)) +>makeBox : Symbol(makeBox, Decl(instantiationExpressions.ts, 134, 1)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 143, 9)) type StringBox = Box; // { value: string } ->StringBox : Symbol(StringBox, Decl(instantiationExpressions.ts, 139, 44)) ->Box : Symbol(Box, Decl(instantiationExpressions.ts, 137, 37)) +>StringBox : Symbol(StringBox, Decl(instantiationExpressions.ts, 143, 44)) +>Box : Symbol(Box, Decl(instantiationExpressions.ts, 141, 37)) type A = InstanceType>; // U[] ->A : Symbol(A, Decl(instantiationExpressions.ts, 140, 29)) ->U : Symbol(U, Decl(instantiationExpressions.ts, 142, 7)) +>A : Symbol(A, Decl(instantiationExpressions.ts, 144, 29)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 146, 7)) >InstanceType : Symbol(InstanceType, Decl(lib.es5.d.ts, --, --)) >Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) ->U : Symbol(U, Decl(instantiationExpressions.ts, 142, 7)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 146, 7)) declare const g1: { ->g1 : Symbol(g1, Decl(instantiationExpressions.ts, 144, 13)) +>g1 : Symbol(g1, Decl(instantiationExpressions.ts, 148, 13)) (a: T): { a: T }; ->T : Symbol(T, Decl(instantiationExpressions.ts, 145, 5)) ->a : Symbol(a, Decl(instantiationExpressions.ts, 145, 8)) ->T : Symbol(T, Decl(instantiationExpressions.ts, 145, 5)) ->a : Symbol(a, Decl(instantiationExpressions.ts, 145, 16)) ->T : Symbol(T, Decl(instantiationExpressions.ts, 145, 5)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 149, 5)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 149, 8)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 149, 5)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 149, 16)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 149, 5)) new (b: U): { b: U }; ->U : Symbol(U, Decl(instantiationExpressions.ts, 146, 9)) ->b : Symbol(b, Decl(instantiationExpressions.ts, 146, 12)) ->U : Symbol(U, Decl(instantiationExpressions.ts, 146, 9)) ->b : Symbol(b, Decl(instantiationExpressions.ts, 146, 20)) ->U : Symbol(U, Decl(instantiationExpressions.ts, 146, 9)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 150, 9)) +>b : Symbol(b, Decl(instantiationExpressions.ts, 150, 12)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 150, 9)) +>b : Symbol(b, Decl(instantiationExpressions.ts, 150, 20)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 150, 9)) } type T30 = typeof g1; // { (a: V) => { a: V }; new (b: V) => { b: V }; } ->T30 : Symbol(T30, Decl(instantiationExpressions.ts, 147, 1)) ->V : Symbol(V, Decl(instantiationExpressions.ts, 149, 9)) ->g1 : Symbol(g1, Decl(instantiationExpressions.ts, 144, 13)) ->V : Symbol(V, Decl(instantiationExpressions.ts, 149, 9)) +>T30 : Symbol(T30, Decl(instantiationExpressions.ts, 151, 1)) +>V : Symbol(V, Decl(instantiationExpressions.ts, 153, 9)) +>g1 : Symbol(g1, Decl(instantiationExpressions.ts, 148, 13)) +>V : Symbol(V, Decl(instantiationExpressions.ts, 153, 9)) type T31 = ReturnType>; // { a: A } ->T31 : Symbol(T31, Decl(instantiationExpressions.ts, 149, 27)) ->A : Symbol(A, Decl(instantiationExpressions.ts, 150, 9)) +>T31 : Symbol(T31, Decl(instantiationExpressions.ts, 153, 27)) +>A : Symbol(A, Decl(instantiationExpressions.ts, 154, 9)) >ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) ->T30 : Symbol(T30, Decl(instantiationExpressions.ts, 147, 1)) ->A : Symbol(A, Decl(instantiationExpressions.ts, 150, 9)) +>T30 : Symbol(T30, Decl(instantiationExpressions.ts, 151, 1)) +>A : Symbol(A, Decl(instantiationExpressions.ts, 154, 9)) type T32 = InstanceType>; // { b: B } ->T32 : Symbol(T32, Decl(instantiationExpressions.ts, 150, 33)) ->B : Symbol(B, Decl(instantiationExpressions.ts, 151, 9)) +>T32 : Symbol(T32, Decl(instantiationExpressions.ts, 154, 33)) +>B : Symbol(B, Decl(instantiationExpressions.ts, 155, 9)) >InstanceType : Symbol(InstanceType, Decl(lib.es5.d.ts, --, --)) ->T30 : Symbol(T30, Decl(instantiationExpressions.ts, 147, 1)) ->B : Symbol(B, Decl(instantiationExpressions.ts, 151, 9)) +>T30 : Symbol(T30, Decl(instantiationExpressions.ts, 151, 1)) +>B : Symbol(B, Decl(instantiationExpressions.ts, 155, 9)) declare const g2: { ->g2 : Symbol(g2, Decl(instantiationExpressions.ts, 153, 13)) +>g2 : Symbol(g2, Decl(instantiationExpressions.ts, 157, 13)) (a: T): T; ->T : Symbol(T, Decl(instantiationExpressions.ts, 154, 5)) ->a : Symbol(a, Decl(instantiationExpressions.ts, 154, 23)) ->T : Symbol(T, Decl(instantiationExpressions.ts, 154, 5)) ->T : Symbol(T, Decl(instantiationExpressions.ts, 154, 5)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 158, 5)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 158, 23)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 158, 5)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 158, 5)) new (b: T): T; ->T : Symbol(T, Decl(instantiationExpressions.ts, 155, 9)) ->b : Symbol(b, Decl(instantiationExpressions.ts, 155, 27)) ->T : Symbol(T, Decl(instantiationExpressions.ts, 155, 9)) ->T : Symbol(T, Decl(instantiationExpressions.ts, 155, 9)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 159, 9)) +>b : Symbol(b, Decl(instantiationExpressions.ts, 159, 27)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 159, 9)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 159, 9)) } type T40 = typeof g2; // Error ->T40 : Symbol(T40, Decl(instantiationExpressions.ts, 156, 1)) ->U : Symbol(U, Decl(instantiationExpressions.ts, 158, 9)) ->g2 : Symbol(g2, Decl(instantiationExpressions.ts, 153, 13)) ->U : Symbol(U, Decl(instantiationExpressions.ts, 158, 9)) +>T40 : Symbol(T40, Decl(instantiationExpressions.ts, 160, 1)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 162, 9)) +>g2 : Symbol(g2, Decl(instantiationExpressions.ts, 157, 13)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 162, 9)) type T41 = typeof g2; // Error ->T41 : Symbol(T41, Decl(instantiationExpressions.ts, 158, 42)) ->U : Symbol(U, Decl(instantiationExpressions.ts, 159, 9)) ->g2 : Symbol(g2, Decl(instantiationExpressions.ts, 153, 13)) ->U : Symbol(U, Decl(instantiationExpressions.ts, 159, 9)) +>T41 : Symbol(T41, Decl(instantiationExpressions.ts, 162, 42)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 163, 9)) +>g2 : Symbol(g2, Decl(instantiationExpressions.ts, 157, 13)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 163, 9)) declare const g3: { ->g3 : Symbol(g3, Decl(instantiationExpressions.ts, 161, 13)) +>g3 : Symbol(g3, Decl(instantiationExpressions.ts, 165, 13)) (a: T): T; ->T : Symbol(T, Decl(instantiationExpressions.ts, 162, 5)) ->a : Symbol(a, Decl(instantiationExpressions.ts, 162, 23)) ->T : Symbol(T, Decl(instantiationExpressions.ts, 162, 5)) ->T : Symbol(T, Decl(instantiationExpressions.ts, 162, 5)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 166, 5)) +>a : Symbol(a, Decl(instantiationExpressions.ts, 166, 23)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 166, 5)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 166, 5)) new (b: T): T; ->T : Symbol(T, Decl(instantiationExpressions.ts, 163, 9)) ->Q : Symbol(Q, Decl(instantiationExpressions.ts, 163, 26)) ->b : Symbol(b, Decl(instantiationExpressions.ts, 163, 30)) ->T : Symbol(T, Decl(instantiationExpressions.ts, 163, 9)) ->T : Symbol(T, Decl(instantiationExpressions.ts, 163, 9)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 167, 9)) +>Q : Symbol(Q, Decl(instantiationExpressions.ts, 167, 26)) +>b : Symbol(b, Decl(instantiationExpressions.ts, 167, 30)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 167, 9)) +>T : Symbol(T, Decl(instantiationExpressions.ts, 167, 9)) } type T50 = typeof g3; // (a: U) => U ->T50 : Symbol(T50, Decl(instantiationExpressions.ts, 164, 1)) ->U : Symbol(U, Decl(instantiationExpressions.ts, 166, 9)) ->g3 : Symbol(g3, Decl(instantiationExpressions.ts, 161, 13)) ->U : Symbol(U, Decl(instantiationExpressions.ts, 166, 9)) +>T50 : Symbol(T50, Decl(instantiationExpressions.ts, 168, 1)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 170, 9)) +>g3 : Symbol(g3, Decl(instantiationExpressions.ts, 165, 13)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 170, 9)) type T51 = typeof g3; // (b: U) => U ->T51 : Symbol(T51, Decl(instantiationExpressions.ts, 166, 42)) ->U : Symbol(U, Decl(instantiationExpressions.ts, 167, 9)) ->g3 : Symbol(g3, Decl(instantiationExpressions.ts, 161, 13)) ->U : Symbol(U, Decl(instantiationExpressions.ts, 167, 9)) +>T51 : Symbol(T51, Decl(instantiationExpressions.ts, 170, 42)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 171, 9)) +>g3 : Symbol(g3, Decl(instantiationExpressions.ts, 165, 13)) +>U : Symbol(U, Decl(instantiationExpressions.ts, 171, 9)) diff --git a/tests/baselines/reference/instantiationExpressions.types b/tests/baselines/reference/instantiationExpressions.types index 8a14081739ab1..43a71f42d3ea5 100644 --- a/tests/baselines/reference/instantiationExpressions.types +++ b/tests/baselines/reference/instantiationExpressions.types @@ -383,6 +383,18 @@ function f37(f: ((a: T) => T) | (new (a: string, b: number) => string[])) { >f : ((a: T) => T) | (new (a: string, b: number) => string[]) } +function f38(x: A) => A) | ((x: B) => B[]), U>(f: T | U | ((x: C) => C[][])) { +>f38 : (x: A) => A) | ((x: B) => B[]), U>(f: T | U | ((x: C) => C[][])) => void +>x : A +>x : B +>f : T | U | ((x: C) => C[][]) +>x : C + + let fs = f; // U | ((x: string) => string) | ((x: string) => string[]) | ((x: string) => string[][]) +>fs : U | ((x: string) => string) | ((x: string) => string[]) | ((x: string) => string[][]) +>f : T | U | ((x: C) => C[][]) +} + function makeBox(value: T) { >makeBox : (value: T) => { value: T; } >value : T diff --git a/tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts b/tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts index 00e375c8836d0..ce9d23aacc96d 100644 --- a/tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts +++ b/tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressions.ts @@ -133,6 +133,10 @@ function f37(f: ((a: T) => T) | (new (a: string, b: number) => string[])) { let fs = f; // Error, 'new (a: string, b: number) => string[]' has no applicable signatures } +function f38(x: A) => A) | ((x: B) => B[]), U>(f: T | U | ((x: C) => C[][])) { + let fs = f; // U | ((x: string) => string) | ((x: string) => string[]) | ((x: string) => string[][]) +} + function makeBox(value: T) { return { value }; } From 3d496681599994de09aa5c5b2b115750c7d681e5 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 30 Jan 2022 07:37:42 -0800 Subject: [PATCH 14/16] More permissive parsing of type arguments in member expressions --- src/compiler/diagnosticMessages.json | 4 -- src/compiler/parser.ts | 92 +++++++++++++--------------- src/compiler/types.ts | 2 +- 3 files changed, 42 insertions(+), 56 deletions(-) diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index c25e7c4d3c659..3d09c542cd991 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1140,10 +1140,6 @@ "category": "Error", "code": 1383 }, - "A 'new' expression with type arguments must always be followed by a parenthesized argument list.": { - "category": "Error", - "code": 1384 - }, "Function type notation must be parenthesized when used in a union type.": { "category": "Error", "code": 1385 diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 8392efa650d28..9134a6d2434fa 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -5431,12 +5431,6 @@ namespace ts { continue; } - if (!questionDotToken && token() === SyntaxKind.ExclamationToken && !scanner.hasPrecedingLineBreak()) { - nextToken(); - expression = finishNode(factory.createNonNullExpression(expression), pos); - continue; - } - // when in the [Decorator] context, we do not parse ElementAccess as it could be part of a ComputedPropertyName if ((questionDotToken || !inDecoratorContext()) && parseOptional(SyntaxKind.OpenBracketToken)) { expression = parseElementAccessExpressionRest(pos, expression, questionDotToken); @@ -5444,10 +5438,26 @@ namespace ts { } if (isTemplateStartOfTaggedTemplate()) { - expression = parseTaggedTemplateRest(pos, expression, questionDotToken, /*typeArguments*/ undefined); + // Absorb type arguments into TemplateExpression when preceding expression is ExpressionWithTypeArguments + expression = !questionDotToken && expression.kind === SyntaxKind.ExpressionWithTypeArguments ? + parseTaggedTemplateRest(pos, (expression as ExpressionWithTypeArguments).expression, questionDotToken, (expression as ExpressionWithTypeArguments).typeArguments) : + parseTaggedTemplateRest(pos, expression, questionDotToken, /*typeArguments*/ undefined); continue; } + if (!questionDotToken) { + if (token() === SyntaxKind.ExclamationToken && !scanner.hasPrecedingLineBreak()) { + nextToken(); + expression = finishNode(factory.createNonNullExpression(expression), pos); + continue; + } + const typeArguments = tryParse(parseTypeArgumentsInExpression); + if (typeArguments) { + expression = finishNode(factory.createExpressionWithTypeArguments(expression, typeArguments), pos); + continue; + } + } + return expression as MemberExpression; } } @@ -5474,42 +5484,30 @@ namespace ts { function parseCallExpressionRest(pos: number, expression: LeftHandSideExpression): LeftHandSideExpression { while (true) { expression = parseMemberExpressionRest(pos, expression, /*allowOptionalChain*/ true); + let typeArguments: NodeArray | undefined; const questionDotToken = parseOptionalToken(SyntaxKind.QuestionDotToken); - // handle 'foo<()' - // parse template arguments only in TypeScript files (not in JavaScript files). - if ((contextFlags & NodeFlags.JavaScriptFile) === 0 && (token() === SyntaxKind.LessThanToken || token() === SyntaxKind.LessThanLessThanToken)) { - // See if this is the start of a generic invocation. If so, consume it and - // keep checking for postfix expressions. Otherwise, it's just a '<' that's - // part of an arithmetic expression. Break out so we consume it higher in the - // stack. - const typeArguments = tryParse(parseTypeArgumentsInExpression); - if (typeArguments) { - if (isTemplateStartOfTaggedTemplate()) { - expression = parseTaggedTemplateRest(pos, expression, questionDotToken, typeArguments); - continue; - } - if (questionDotToken || token() === SyntaxKind.OpenParenToken) { - const argumentList = parseArgumentList(); - const callExpr = questionDotToken || tryReparseOptionalChain(expression) ? - factory.createCallChain(expression, questionDotToken, typeArguments, argumentList) : - factory.createCallExpression(expression, typeArguments, argumentList); - expression = finishNode(callExpr, pos); - continue; - } - expression = finishNode(factory.createExpressionWithTypeArguments(expression, typeArguments), pos); - break; + if (questionDotToken) { + typeArguments = tryParse(parseTypeArgumentsInExpression); + if (isTemplateStartOfTaggedTemplate()) { + expression = parseTaggedTemplateRest(pos, expression, questionDotToken, typeArguments); + continue; } } - else if (token() === SyntaxKind.OpenParenToken) { + if (typeArguments || token() === SyntaxKind.OpenParenToken) { + // Absorb type arguments into CallExpression when preceding expression is ExpressionWithTypeArguments + if (!questionDotToken && expression.kind === SyntaxKind.ExpressionWithTypeArguments) { + typeArguments = (expression as ExpressionWithTypeArguments).typeArguments; + expression = (expression as ExpressionWithTypeArguments).expression; + } const argumentList = parseArgumentList(); const callExpr = questionDotToken || tryReparseOptionalChain(expression) ? - factory.createCallChain(expression, questionDotToken, /*typeArguments*/ undefined, argumentList) : - factory.createCallExpression(expression, /*typeArguments*/ undefined, argumentList); + factory.createCallChain(expression, questionDotToken, typeArguments, argumentList) : + factory.createCallExpression(expression, typeArguments, argumentList); expression = finishNode(callExpr, pos); continue; } if (questionDotToken) { - // We failed to parse anything, so report a missing identifier here. + // We parsed `?.` but then failed to parse anything, so report a missing identifier here. const name = createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ false, Diagnostics.Identifier_expected); expression = finishNode(factory.createPropertyAccessChain(expression, questionDotToken, name), pos); } @@ -5561,6 +5559,7 @@ namespace ts { // falls through case SyntaxKind.CommaToken: // foo, case SyntaxKind.DotToken: // foo. + case SyntaxKind.QuestionDotToken: // foo?. case SyntaxKind.CloseParenToken: // foo) case SyntaxKind.CloseBracketToken: // foo] case SyntaxKind.ColonToken: // foo: @@ -5788,25 +5787,16 @@ namespace ts { const name = parseIdentifierName(); return finishNode(factory.createMetaProperty(SyntaxKind.NewKeyword, name), pos); } - const expressionPos = getNodePos(); - let expression = parseMemberExpressionRest(expressionPos, parsePrimaryExpression(), /*allowOptionalChain*/ false); - let typeArguments = tryParse(parseTypeArgumentsInExpression); - if (isTemplateStartOfTaggedTemplate()) { - Debug.assert(!!typeArguments, - "Expected a type argument list; all plain tagged template starts should be consumed in 'parseMemberExpressionRest'"); - expression = parseTaggedTemplateRest(expressionPos, expression, /*optionalChain*/ undefined, typeArguments); - typeArguments = undefined; - } - - let argumentsArray: NodeArray | undefined; - if (token() === SyntaxKind.OpenParenToken) { - argumentsArray = parseArgumentList(); - } - else if (typeArguments) { - parseErrorAt(pos, scanner.getStartPos(), Diagnostics.A_new_expression_with_type_arguments_must_always_be_followed_by_a_parenthesized_argument_list); + let expression: LeftHandSideExpression = parseMemberExpressionRest(expressionPos, parsePrimaryExpression(), /*allowOptionalChain*/ false); + let typeArguments: NodeArray | undefined; + // Absorb type arguments into NewExpression when preceding expression is ExpressionWithTypeArguments + if (expression.kind === SyntaxKind.ExpressionWithTypeArguments) { + typeArguments = (expression as ExpressionWithTypeArguments).typeArguments; + expression = (expression as ExpressionWithTypeArguments).expression; } - return finishNode(factory.createNewExpression(expression, typeArguments, argumentsArray), pos); + const argumentList = token() === SyntaxKind.OpenParenToken ? parseArgumentList() : undefined; + return finishNode(factory.createNewExpression(expression, typeArguments, argumentList), pos); } // STATEMENTS diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 095d25fdae5d9..f79c86878dbd1 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2444,7 +2444,7 @@ namespace ts { readonly expression: ImportExpression; } - export interface ExpressionWithTypeArguments extends LeftHandSideExpression, NodeWithTypeArguments { + export interface ExpressionWithTypeArguments extends MemberExpression, NodeWithTypeArguments { readonly kind: SyntaxKind.ExpressionWithTypeArguments; readonly expression: LeftHandSideExpression; } From 2d79e4f754791be4c3b05ad757678eaafaf66d5f Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 30 Jan 2022 07:37:57 -0800 Subject: [PATCH 15/16] Update tests --- .../compiler/genericCallsWithoutParens.ts | 8 ------ .../genericConstructExpressionWithoutArgs.ts | 9 ------ .../genericObjectCreationWithoutTypeArgs.ts | 4 +-- .../newOperator/newOperatorErrorCases.ts | 2 +- .../instantiationExpressionErrors.ts | 28 +++++++++++++------ 5 files changed, 23 insertions(+), 28 deletions(-) delete mode 100644 tests/cases/compiler/genericCallsWithoutParens.ts delete mode 100644 tests/cases/compiler/genericConstructExpressionWithoutArgs.ts diff --git a/tests/cases/compiler/genericCallsWithoutParens.ts b/tests/cases/compiler/genericCallsWithoutParens.ts deleted file mode 100644 index 72efafd62d754..0000000000000 --- a/tests/cases/compiler/genericCallsWithoutParens.ts +++ /dev/null @@ -1,8 +0,0 @@ -function f() { } -var r = f; // parse error - -class C { - foo: T; -} -var c = new C; // parse error - diff --git a/tests/cases/compiler/genericConstructExpressionWithoutArgs.ts b/tests/cases/compiler/genericConstructExpressionWithoutArgs.ts deleted file mode 100644 index 3c0c2fc4c72f3..0000000000000 --- a/tests/cases/compiler/genericConstructExpressionWithoutArgs.ts +++ /dev/null @@ -1,9 +0,0 @@ -class B { } -var b = new B; // no error - -class C { - x: T; -} - -var c = new C // C -var c2 = new C // error, type params are actually part of the arg list so you need both diff --git a/tests/cases/compiler/genericObjectCreationWithoutTypeArgs.ts b/tests/cases/compiler/genericObjectCreationWithoutTypeArgs.ts index 319127c6f585c..979551dd34e1a 100644 --- a/tests/cases/compiler/genericObjectCreationWithoutTypeArgs.ts +++ b/tests/cases/compiler/genericObjectCreationWithoutTypeArgs.ts @@ -3,6 +3,6 @@ class SS{ } var x1 = new SS(); // OK -var x2 = new SS < number>; // Correctly give error +var x2 = new SS; // OK var x3 = new SS(); // OK -var x4 = new SS; // Should be allowed, but currently give error ('supplied parameters do not match any signature of the call target') +var x4 = new SS; // OK diff --git a/tests/cases/conformance/expressions/newOperator/newOperatorErrorCases.ts b/tests/cases/conformance/expressions/newOperator/newOperatorErrorCases.ts index 8d2ee346a73ad..3279a42a137ab 100644 --- a/tests/cases/conformance/expressions/newOperator/newOperatorErrorCases.ts +++ b/tests/cases/conformance/expressions/newOperator/newOperatorErrorCases.ts @@ -29,7 +29,7 @@ var b = new C0 32, ''; // Parse error // Generic construct expression with no parentheses var c1 = new T; var c1: T<{}>; -var c2 = new T; // Parse error +var c2 = new T; // Ok // Construct expression of non-void returning function diff --git a/tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts b/tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts index 835524ba9ea66..c34a12f13bb80 100644 --- a/tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts +++ b/tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts @@ -1,20 +1,32 @@ // @strict: true // @declaration: true -declare let f: any; +declare let f: { (): T, g(): U }; -// Type arguments only permitted at end of member expression +// Type arguments in member expressions -const a1 = f; -const a2 = f.g; -const a3 = f.g; -const a4 = f.g; +const a1 = f; // { (): number; g(): U; } +const a2 = f.g; // () => number +const a3 = f.g; // () => U +const a4 = f.g; // () => number +const a5 = f['g']; // () => number -// Type arguments must follow ?. token +// `[` is an expression starter and cannot immediately follow a type argument list -const b1 = f?.; +const a6 = f['g']; // Error +const a7 = (f)['g']; + +// An `<` cannot immediately follow a type argument list + +const a8 = f; // Relational operator error +const a9 = (f); // Error, no applicable signatures + +// Type arguments with `?.` token + +const b1 = f?.; // Error, `(` expected const b2 = f?.(); const b3 = f?.(); +const b4 = f?.(); // Error, expected no type arguments // Parsed as function call, even though this differs from JavaScript From 3e8d70dee160f5aea235d688264652cb66fd973a Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sun, 30 Jan 2022 07:48:18 -0800 Subject: [PATCH 16/16] Accept new baselines --- .../reference/api/tsserverlibrary.d.ts | 2 +- tests/baselines/reference/api/typescript.d.ts | 2 +- .../genericCallWithoutArgs.errors.txt | 6 +- .../reference/genericCallWithoutArgs.js | 2 +- .../reference/genericCallWithoutArgs.types | 2 + ...icObjectCreationWithoutTypeArgs.errors.txt | 15 -- .../genericObjectCreationWithoutTypeArgs.js | 8 +- ...nericObjectCreationWithoutTypeArgs.symbols | 4 +- ...genericObjectCreationWithoutTypeArgs.types | 6 +- .../instantiationExpressionErrors.errors.txt | 108 ++++++-------- .../instantiationExpressionErrors.js | 91 ++++++++---- .../instantiationExpressionErrors.symbols | 71 +++++++--- .../instantiationExpressionErrors.types | 132 ++++++++++++------ .../newOperatorErrorCases.errors.txt | 7 +- .../reference/newOperatorErrorCases.js | 4 +- .../reference/newOperatorErrorCases.symbols | 2 +- .../reference/newOperatorErrorCases.types | 2 +- .../parserConstructorAmbiguity3.errors.txt | 5 +- .../parserMemberAccessExpression1.errors.txt | 14 +- .../parserMemberAccessExpression1.js | 6 +- .../parserMemberAccessExpression1.types | 6 +- ...erMemberAccessOffOfGenericType1.errors.txt | 13 +- .../parserMemberAccessOffOfGenericType1.js | 3 +- ...arserMemberAccessOffOfGenericType1.symbols | 1 - .../parserMemberAccessOffOfGenericType1.types | 4 +- ...ggedTemplatesWithTypeArguments2.errors.txt | 11 +- .../taggedTemplatesWithTypeArguments2.js | 4 +- .../taggedTemplatesWithTypeArguments2.types | 2 - 28 files changed, 294 insertions(+), 239 deletions(-) delete mode 100644 tests/baselines/reference/genericObjectCreationWithoutTypeArgs.errors.txt diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index ad1817c9ea3f0..7da2573ebe6f6 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -1285,7 +1285,7 @@ declare namespace ts { export interface ImportCall extends CallExpression { readonly expression: ImportExpression; } - export interface ExpressionWithTypeArguments extends LeftHandSideExpression, NodeWithTypeArguments { + export interface ExpressionWithTypeArguments extends MemberExpression, NodeWithTypeArguments { readonly kind: SyntaxKind.ExpressionWithTypeArguments; readonly expression: LeftHandSideExpression; } diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 11fa7acdabfda..8d90f970bbfa2 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -1285,7 +1285,7 @@ declare namespace ts { export interface ImportCall extends CallExpression { readonly expression: ImportExpression; } - export interface ExpressionWithTypeArguments extends LeftHandSideExpression, NodeWithTypeArguments { + export interface ExpressionWithTypeArguments extends MemberExpression, NodeWithTypeArguments { readonly kind: SyntaxKind.ExpressionWithTypeArguments; readonly expression: LeftHandSideExpression; } diff --git a/tests/baselines/reference/genericCallWithoutArgs.errors.txt b/tests/baselines/reference/genericCallWithoutArgs.errors.txt index fe8e0d03e021c..75a2d51a1da3e 100644 --- a/tests/baselines/reference/genericCallWithoutArgs.errors.txt +++ b/tests/baselines/reference/genericCallWithoutArgs.errors.txt @@ -1,4 +1,4 @@ -tests/cases/compiler/genericCallWithoutArgs.ts(4,17): error TS1005: ';' expected. +tests/cases/compiler/genericCallWithoutArgs.ts(4,18): error TS1003: Identifier expected. ==== tests/cases/compiler/genericCallWithoutArgs.ts (1 errors) ==== @@ -6,5 +6,5 @@ tests/cases/compiler/genericCallWithoutArgs.ts(4,17): error TS1005: ';' expected } f. - ~ -!!! error TS1005: ';' expected. \ No newline at end of file + +!!! error TS1003: Identifier expected. \ No newline at end of file diff --git a/tests/baselines/reference/genericCallWithoutArgs.js b/tests/baselines/reference/genericCallWithoutArgs.js index 0e4d8446f999c..aab48f5e047c6 100644 --- a/tests/baselines/reference/genericCallWithoutArgs.js +++ b/tests/baselines/reference/genericCallWithoutArgs.js @@ -7,4 +7,4 @@ f. //// [genericCallWithoutArgs.js] function f(x, y) { } -f; +f.; diff --git a/tests/baselines/reference/genericCallWithoutArgs.types b/tests/baselines/reference/genericCallWithoutArgs.types index 54302dde335d4..82c32a2ad0444 100644 --- a/tests/baselines/reference/genericCallWithoutArgs.types +++ b/tests/baselines/reference/genericCallWithoutArgs.types @@ -6,5 +6,7 @@ function f(x: X, y: Y) { } f. +>f. : any >f : (x: X, y: Y) => void +> : any diff --git a/tests/baselines/reference/genericObjectCreationWithoutTypeArgs.errors.txt b/tests/baselines/reference/genericObjectCreationWithoutTypeArgs.errors.txt deleted file mode 100644 index f4ea0db74e4ce..0000000000000 --- a/tests/baselines/reference/genericObjectCreationWithoutTypeArgs.errors.txt +++ /dev/null @@ -1,15 +0,0 @@ -tests/cases/compiler/genericObjectCreationWithoutTypeArgs.ts(6,9): error TS1384: A 'new' expression with type arguments must always be followed by a parenthesized argument list. - - -==== tests/cases/compiler/genericObjectCreationWithoutTypeArgs.ts (1 errors) ==== - class SS{ - - } - - var x1 = new SS(); // OK - var x2 = new SS < number>; // Correctly give error - ~~~~~~~~~~~~~~~~~ -!!! error TS1384: A 'new' expression with type arguments must always be followed by a parenthesized argument list. - var x3 = new SS(); // OK - var x4 = new SS; // Should be allowed, but currently give error ('supplied parameters do not match any signature of the call target') - \ No newline at end of file diff --git a/tests/baselines/reference/genericObjectCreationWithoutTypeArgs.js b/tests/baselines/reference/genericObjectCreationWithoutTypeArgs.js index c0226ca9c410d..67be64ea8d533 100644 --- a/tests/baselines/reference/genericObjectCreationWithoutTypeArgs.js +++ b/tests/baselines/reference/genericObjectCreationWithoutTypeArgs.js @@ -4,9 +4,9 @@ class SS{ } var x1 = new SS(); // OK -var x2 = new SS < number>; // Correctly give error +var x2 = new SS; // OK var x3 = new SS(); // OK -var x4 = new SS; // Should be allowed, but currently give error ('supplied parameters do not match any signature of the call target') +var x4 = new SS; // OK //// [genericObjectCreationWithoutTypeArgs.js] @@ -16,6 +16,6 @@ var SS = /** @class */ (function () { return SS; }()); var x1 = new SS(); // OK -var x2 = new SS; // Correctly give error +var x2 = new SS; // OK var x3 = new SS(); // OK -var x4 = new SS; // Should be allowed, but currently give error ('supplied parameters do not match any signature of the call target') +var x4 = new SS; // OK diff --git a/tests/baselines/reference/genericObjectCreationWithoutTypeArgs.symbols b/tests/baselines/reference/genericObjectCreationWithoutTypeArgs.symbols index 3b3291ae79e24..34d6a510dc546 100644 --- a/tests/baselines/reference/genericObjectCreationWithoutTypeArgs.symbols +++ b/tests/baselines/reference/genericObjectCreationWithoutTypeArgs.symbols @@ -9,7 +9,7 @@ var x1 = new SS(); // OK >x1 : Symbol(x1, Decl(genericObjectCreationWithoutTypeArgs.ts, 4, 3)) >SS : Symbol(SS, Decl(genericObjectCreationWithoutTypeArgs.ts, 0, 0)) -var x2 = new SS < number>; // Correctly give error +var x2 = new SS; // OK >x2 : Symbol(x2, Decl(genericObjectCreationWithoutTypeArgs.ts, 5, 3)) >SS : Symbol(SS, Decl(genericObjectCreationWithoutTypeArgs.ts, 0, 0)) @@ -17,7 +17,7 @@ var x3 = new SS(); // OK >x3 : Symbol(x3, Decl(genericObjectCreationWithoutTypeArgs.ts, 6, 3)) >SS : Symbol(SS, Decl(genericObjectCreationWithoutTypeArgs.ts, 0, 0)) -var x4 = new SS; // Should be allowed, but currently give error ('supplied parameters do not match any signature of the call target') +var x4 = new SS; // OK >x4 : Symbol(x4, Decl(genericObjectCreationWithoutTypeArgs.ts, 7, 3)) >SS : Symbol(SS, Decl(genericObjectCreationWithoutTypeArgs.ts, 0, 0)) diff --git a/tests/baselines/reference/genericObjectCreationWithoutTypeArgs.types b/tests/baselines/reference/genericObjectCreationWithoutTypeArgs.types index dad4ebdc4dde1..8592a2d157765 100644 --- a/tests/baselines/reference/genericObjectCreationWithoutTypeArgs.types +++ b/tests/baselines/reference/genericObjectCreationWithoutTypeArgs.types @@ -9,9 +9,9 @@ var x1 = new SS(); // OK >new SS() : SS >SS : typeof SS -var x2 = new SS < number>; // Correctly give error +var x2 = new SS; // OK >x2 : SS ->new SS < number> : SS +>new SS : SS >SS : typeof SS var x3 = new SS(); // OK @@ -19,7 +19,7 @@ var x3 = new SS(); // OK >new SS() : SS >SS : typeof SS -var x4 = new SS; // Should be allowed, but currently give error ('supplied parameters do not match any signature of the call target') +var x4 = new SS; // OK >x4 : SS >new SS : SS >SS : typeof SS diff --git a/tests/baselines/reference/instantiationExpressionErrors.errors.txt b/tests/baselines/reference/instantiationExpressionErrors.errors.txt index 7cd0ad52d97bb..d0ded2ca91756 100644 --- a/tests/baselines/reference/instantiationExpressionErrors.errors.txt +++ b/tests/baselines/reference/instantiationExpressionErrors.errors.txt @@ -1,91 +1,75 @@ -tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(5,14): error TS2635: Type 'any' has no signatures for which the type argument list is applicable. -tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(6,16): error TS2635: Type 'any' has no signatures for which the type argument list is applicable. -tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(7,14): error TS2635: Type 'any' has no signatures for which the type argument list is applicable. -tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(7,21): error TS1005: ',' expected. -tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(7,22): error TS2451: Cannot redeclare block-scoped variable 'g'. -tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(7,22): error TS7005: Variable 'g' implicitly has an 'any' type. -tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(8,14): error TS2635: Type 'any' has no signatures for which the type argument list is applicable. -tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(8,21): error TS1005: ',' expected. -tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(8,22): error TS2451: Cannot redeclare block-scoped variable 'g'. -tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(8,22): error TS7005: Variable 'g' implicitly has an 'any' type. -tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(8,23): error TS1005: ',' expected. -tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(8,31): error TS1109: Expression expected. -tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(12,12): error TS2347: Untyped function calls may not accept type arguments. -tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(12,23): error TS1005: '(' expected. -tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(13,12): error TS2347: Untyped function calls may not accept type arguments. -tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(14,14): error TS2693: 'number' only refers to a type, but is being used as a value here. -tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(14,21): error TS1109: Expression expected. -tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(18,12): error TS2347: Untyped function calls may not accept type arguments. -tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(28,14): error TS2635: Type 'any' has no signatures for which the type argument list is applicable. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(13,12): error TS2365: Operator '>' cannot be applied to types 'boolean' and 'string[]'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(13,14): error TS2693: 'number' only refers to a type, but is being used as a value here. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(18,12): error TS2365: Operator '>' cannot be applied to types 'boolean' and 'number'. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(18,14): error TS2693: 'number' only refers to a type, but is being used as a value here. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(18,29): error TS1109: Expression expected. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(19,24): error TS2635: Type '{ (): number; g(): U; }' has no signatures for which the type argument list is applicable. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(23,23): error TS1005: '(' expected. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(26,24): error TS2558: Expected 0 type arguments, but got 1. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(31,2): error TS2554: Expected 0 arguments, but got 1. +tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts(35,12): error TS2365: Operator '<' cannot be applied to types '{ (): T; g(): U; }' and 'boolean'. -==== tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts (19 errors) ==== - declare let f: any; +==== tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts (10 errors) ==== + declare let f: { (): T, g(): U }; - // Type arguments only permitted at end of member expression + // Type arguments in member expressions - const a1 = f; - ~~~~~~ -!!! error TS2635: Type 'any' has no signatures for which the type argument list is applicable. - const a2 = f.g; - ~~~~~~ -!!! error TS2635: Type 'any' has no signatures for which the type argument list is applicable. - const a3 = f.g; + const a1 = f; // { (): number; g(): U; } + const a2 = f.g; // () => number + const a3 = f.g; // () => U + const a4 = f.g; // () => number + const a5 = f['g']; // () => number + + // `[` is an expression starter and cannot immediately follow a type argument list + + const a6 = f['g']; // Error + ~~~~~~~~~~~~~~ +!!! error TS2365: Operator '>' cannot be applied to types 'boolean' and 'string[]'. ~~~~~~ -!!! error TS2635: Type 'any' has no signatures for which the type argument list is applicable. - ~ -!!! error TS1005: ',' expected. - ~ -!!! error TS2451: Cannot redeclare block-scoped variable 'g'. - ~ -!!! error TS7005: Variable 'g' implicitly has an 'any' type. - const a4 = f.g; +!!! error TS2693: 'number' only refers to a type, but is being used as a value here. + const a7 = (f)['g']; + + // An `<` cannot immediately follow a type argument list + + const a8 = f; // Relational operator error + ~~~~~~~~~~~~~~~~~ +!!! error TS2365: Operator '>' cannot be applied to types 'boolean' and 'number'. ~~~~~~ -!!! error TS2635: Type 'any' has no signatures for which the type argument list is applicable. - ~ -!!! error TS1005: ',' expected. - ~ -!!! error TS2451: Cannot redeclare block-scoped variable 'g'. - ~ -!!! error TS7005: Variable 'g' implicitly has an 'any' type. - ~ -!!! error TS1005: ',' expected. - ~ +!!! error TS2693: 'number' only refers to a type, but is being used as a value here. + ~ !!! error TS1109: Expression expected. + const a9 = (f); // Error, no applicable signatures + ~~~~~~ +!!! error TS2635: Type '{ (): number; g(): U; }' has no signatures for which the type argument list is applicable. - // Type arguments must follow ?. token + // Type arguments with `?.` token - const b1 = f?.; - ~~~~~~~~~~~ -!!! error TS2347: Untyped function calls may not accept type arguments. + const b1 = f?.; // Error, `(` expected ~ !!! error TS1005: '(' expected. const b2 = f?.(); - ~~~~~~~~~~~~~ -!!! error TS2347: Untyped function calls may not accept type arguments. const b3 = f?.(); - ~~~~~~ -!!! error TS2693: 'number' only refers to a type, but is being used as a value here. - ~~ -!!! error TS1109: Expression expected. + const b4 = f?.(); // Error, expected no type arguments + ~~~~~~ +!!! error TS2558: Expected 0 type arguments, but got 1. // Parsed as function call, even though this differs from JavaScript const x1 = f - ~~~~~~~ (true); - ~~~~~~ -!!! error TS2347: Untyped function calls may not accept type arguments. + ~~~~ +!!! error TS2554: Expected 0 arguments, but got 1. // Parsed as relational expression const x2 = f + ~~~~~~ +!!! error TS2365: Operator '<' cannot be applied to types '{ (): T; g(): U; }' and 'boolean'. true; // Parsed as instantiation expression const x3 = f; - ~~~~ -!!! error TS2635: Type 'any' has no signatures for which the type argument list is applicable. true; \ No newline at end of file diff --git a/tests/baselines/reference/instantiationExpressionErrors.js b/tests/baselines/reference/instantiationExpressionErrors.js index a0324d186a7e9..c0c4d9b5b6818 100644 --- a/tests/baselines/reference/instantiationExpressionErrors.js +++ b/tests/baselines/reference/instantiationExpressionErrors.js @@ -1,18 +1,30 @@ //// [instantiationExpressionErrors.ts] -declare let f: any; +declare let f: { (): T, g(): U }; -// Type arguments only permitted at end of member expression +// Type arguments in member expressions -const a1 = f; -const a2 = f.g; -const a3 = f.g; -const a4 = f.g; +const a1 = f; // { (): number; g(): U; } +const a2 = f.g; // () => number +const a3 = f.g; // () => U +const a4 = f.g; // () => number +const a5 = f['g']; // () => number -// Type arguments must follow ?. token +// `[` is an expression starter and cannot immediately follow a type argument list -const b1 = f?.; +const a6 = f['g']; // Error +const a7 = (f)['g']; + +// An `<` cannot immediately follow a type argument list + +const a8 = f; // Relational operator error +const a9 = (f); // Error, no applicable signatures + +// Type arguments with `?.` token + +const b1 = f?.; // Error, `(` expected const b2 = f?.(); const b3 = f?.(); +const b4 = f?.(); // Error, expected no type arguments // Parsed as function call, even though this differs from JavaScript @@ -32,16 +44,24 @@ true; //// [instantiationExpressionErrors.js] "use strict"; -// Type arguments only permitted at end of member expression -var a1 = (f); -var a2 = (f.g); -var a3 = (f), g; -var a4 = (f), g; -; -// Type arguments must follow ?. token -var b1 = f === null || f === void 0 ? void 0 : f(); +var _a, _b; +// Type arguments in member expressions +var a1 = (f); // { (): number; g(): U; } +var a2 = (f.g); // () => number +var a3 = f.g; // () => U +var a4 = (f.g); // () => number +var a5 = (f['g']); // () => number +// `[` is an expression starter and cannot immediately follow a type argument list +var a6 = f < number > ['g']; // Error +var a7 = (f)['g']; +// An `<` cannot immediately follow a type argument list +var a8 = f < number > ; // Relational operator error +var a9 = ((f)); // Error, no applicable signatures +// Type arguments with `?.` token +var b1 = f === null || f === void 0 ? void 0 : f(); // Error, `(` expected var b2 = f === null || f === void 0 ? void 0 : f(); -var b3 = f < number > ( === null || === void 0 ? void 0 : ()); +var b3 = (_a = (f)) === null || _a === void 0 ? void 0 : _a(); +var b4 = (_b = (f)) === null || _b === void 0 ? void 0 : _b(); // Error, expected no type arguments // Parsed as function call, even though this differs from JavaScript var x1 = f(true); // Parsed as relational expression @@ -53,14 +73,31 @@ true; //// [instantiationExpressionErrors.d.ts] -declare let f: any; -declare const a1: any; -declare const a2: any; -declare const a3: any, g: any; -declare const a4: any, g: any; -declare const b1: any; -declare const b2: any; -declare const b3: boolean; -declare const x1: any; +declare let f: { + (): T; + g(): U; +}; +declare const a1: { + (): number; + g(): U; +}; +declare const a2: () => number; +declare const a3: () => U; +declare const a4: () => number; +declare const a5: () => number; +declare const a6: boolean; +declare const a7: () => U; +declare const a8: boolean; +declare const a9: { + g(): U; +}; +declare const b1: number; +declare const b2: number; +declare const b3: number; +declare const b4: number; +declare const x1: true; declare const x2: boolean; -declare const x3: any; +declare const x3: { + (): true; + g(): U; +}; diff --git a/tests/baselines/reference/instantiationExpressionErrors.symbols b/tests/baselines/reference/instantiationExpressionErrors.symbols index 2e44a94bdaf7b..a9e99be8987a3 100644 --- a/tests/baselines/reference/instantiationExpressionErrors.symbols +++ b/tests/baselines/reference/instantiationExpressionErrors.symbols @@ -1,45 +1,84 @@ === tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts === -declare let f: any; +declare let f: { (): T, g(): U }; >f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) +>T : Symbol(T, Decl(instantiationExpressionErrors.ts, 0, 18)) +>T : Symbol(T, Decl(instantiationExpressionErrors.ts, 0, 18)) +>g : Symbol(g, Decl(instantiationExpressionErrors.ts, 0, 26)) +>U : Symbol(U, Decl(instantiationExpressionErrors.ts, 0, 29)) +>U : Symbol(U, Decl(instantiationExpressionErrors.ts, 0, 29)) -// Type arguments only permitted at end of member expression +// Type arguments in member expressions -const a1 = f; +const a1 = f; // { (): number; g(): U; } >a1 : Symbol(a1, Decl(instantiationExpressionErrors.ts, 4, 5)) >f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) -const a2 = f.g; +const a2 = f.g; // () => number >a2 : Symbol(a2, Decl(instantiationExpressionErrors.ts, 5, 5)) +>f.g : Symbol(g, Decl(instantiationExpressionErrors.ts, 0, 26)) >f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) +>g : Symbol(g, Decl(instantiationExpressionErrors.ts, 0, 26)) -const a3 = f.g; +const a3 = f.g; // () => U >a3 : Symbol(a3, Decl(instantiationExpressionErrors.ts, 6, 5)) +>f.g : Symbol(g, Decl(instantiationExpressionErrors.ts, 0, 26)) >f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) ->g : Symbol(g, Decl(instantiationExpressionErrors.ts, 6, 21)) +>g : Symbol(g, Decl(instantiationExpressionErrors.ts, 0, 26)) -const a4 = f.g; +const a4 = f.g; // () => number >a4 : Symbol(a4, Decl(instantiationExpressionErrors.ts, 7, 5)) +>f.g : Symbol(g, Decl(instantiationExpressionErrors.ts, 0, 26)) >f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) ->g : Symbol(g, Decl(instantiationExpressionErrors.ts, 7, 21)) +>g : Symbol(g, Decl(instantiationExpressionErrors.ts, 0, 26)) -// Type arguments must follow ?. token +const a5 = f['g']; // () => number +>a5 : Symbol(a5, Decl(instantiationExpressionErrors.ts, 8, 5)) +>f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) +>'g' : Symbol(g, Decl(instantiationExpressionErrors.ts, 0, 26)) + +// `[` is an expression starter and cannot immediately follow a type argument list + +const a6 = f['g']; // Error +>a6 : Symbol(a6, Decl(instantiationExpressionErrors.ts, 12, 5)) +>f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) + +const a7 = (f)['g']; +>a7 : Symbol(a7, Decl(instantiationExpressionErrors.ts, 13, 5)) +>f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) +>'g' : Symbol(g, Decl(instantiationExpressionErrors.ts, 0, 26)) + +// An `<` cannot immediately follow a type argument list -const b1 = f?.; ->b1 : Symbol(b1, Decl(instantiationExpressionErrors.ts, 11, 5)) +const a8 = f; // Relational operator error +>a8 : Symbol(a8, Decl(instantiationExpressionErrors.ts, 17, 5)) +>f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) + +const a9 = (f); // Error, no applicable signatures +>a9 : Symbol(a9, Decl(instantiationExpressionErrors.ts, 18, 5)) +>f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) + +// Type arguments with `?.` token + +const b1 = f?.; // Error, `(` expected +>b1 : Symbol(b1, Decl(instantiationExpressionErrors.ts, 22, 5)) >f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) const b2 = f?.(); ->b2 : Symbol(b2, Decl(instantiationExpressionErrors.ts, 12, 5)) +>b2 : Symbol(b2, Decl(instantiationExpressionErrors.ts, 23, 5)) >f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) const b3 = f?.(); ->b3 : Symbol(b3, Decl(instantiationExpressionErrors.ts, 13, 5)) +>b3 : Symbol(b3, Decl(instantiationExpressionErrors.ts, 24, 5)) +>f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) + +const b4 = f?.(); // Error, expected no type arguments +>b4 : Symbol(b4, Decl(instantiationExpressionErrors.ts, 25, 5)) >f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) // Parsed as function call, even though this differs from JavaScript const x1 = f ->x1 : Symbol(x1, Decl(instantiationExpressionErrors.ts, 17, 5)) +>x1 : Symbol(x1, Decl(instantiationExpressionErrors.ts, 29, 5)) >f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) (true); @@ -47,7 +86,7 @@ const x1 = f // Parsed as relational expression const x2 = f ->x2 : Symbol(x2, Decl(instantiationExpressionErrors.ts, 22, 5)) +>x2 : Symbol(x2, Decl(instantiationExpressionErrors.ts, 34, 5)) >f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) true; @@ -55,7 +94,7 @@ true; // Parsed as instantiation expression const x3 = f; ->x3 : Symbol(x3, Decl(instantiationExpressionErrors.ts, 27, 5)) +>x3 : Symbol(x3, Decl(instantiationExpressionErrors.ts, 39, 5)) >f : Symbol(f, Decl(instantiationExpressionErrors.ts, 0, 11)) true; diff --git a/tests/baselines/reference/instantiationExpressionErrors.types b/tests/baselines/reference/instantiationExpressionErrors.types index c40d02411d0ba..3886d802526a1 100644 --- a/tests/baselines/reference/instantiationExpressionErrors.types +++ b/tests/baselines/reference/instantiationExpressionErrors.types @@ -1,58 +1,100 @@ === tests/cases/conformance/types/typeParameters/typeArgumentLists/instantiationExpressionErrors.ts === -declare let f: any; ->f : any - -// Type arguments only permitted at end of member expression - -const a1 = f; ->a1 : any ->f : any - -const a2 = f.g; ->a2 : any ->f.g : any ->f : any ->g : any - -const a3 = f.g; ->a3 : any ->f : any ->g : any - -const a4 = f.g; ->a4 : any ->f : any ->g : any +declare let f: { (): T, g(): U }; +>f : { (): T; g(): U; } +>g : () => U + +// Type arguments in member expressions + +const a1 = f; // { (): number; g(): U; } +>a1 : { (): number; g(): U; } +>f : { (): T; g(): U; } + +const a2 = f.g; // () => number +>a2 : () => number +>f.g : () => U +>f : { (): T; g(): U; } +>g : () => U + +const a3 = f.g; // () => U +>a3 : () => U +>f.g : () => U +>f : { (): T; g(): U; } +>g : () => U + +const a4 = f.g; // () => number +>a4 : () => number +>f.g : () => U +>f : { (): T; g(): U; } +>g : () => U + +const a5 = f['g']; // () => number +>a5 : () => number +>f['g'] : () => U +>f : { (): T; g(): U; } +>'g' : "g" + +// `[` is an expression starter and cannot immediately follow a type argument list + +const a6 = f['g']; // Error +>a6 : boolean +>f['g'] : boolean +>ff : { (): T; g(): U; } +>number : any +>['g'] : string[] +>'g' : "g" + +const a7 = (f)['g']; +>a7 : () => U +>(f)['g'] : () => U +>(f) : { (): number; g(): U; } +>f : { (): T; g(): U; } +>'g' : "g" + +// An `<` cannot immediately follow a type argument list + +const a8 = f; // Relational operator error +>a8 : boolean +>f : boolean +>ff : { (): T; g(): U; } +>number : any > : number > : any -// Type arguments must follow ?. token +const a9 = (f); // Error, no applicable signatures +>a9 : { g(): U; } +>(f) : { (): number; g(): U; } +>f : { (): T; g(): U; } + +// Type arguments with `?.` token -const b1 = f?.; ->b1 : any ->f?. : any ->f : any +const b1 = f?.; // Error, `(` expected +>b1 : number +>f?. : number +>f : { (): T; g(): U; } const b2 = f?.(); ->b2 : any ->f?.() : any ->f : any +>b2 : number +>f?.() : number +>f : { (): T; g(): U; } const b3 = f?.(); ->b3 : boolean ->f?.() : boolean ->ff : any ->number : any ->?.() : any -> : any +>b3 : number +>f?.() : number +>f : { (): T; g(): U; } + +const b4 = f?.(); // Error, expected no type arguments +>b4 : number +>f?.() : number +>f : { (): T; g(): U; } // Parsed as function call, even though this differs from JavaScript const x1 = f ->x1 : any ->f(true) : any ->f : any +>x1 : true +>f(true) : true +>f : { (): T; g(): U; } >true : true (true); @@ -64,7 +106,7 @@ const x2 = f >x2 : boolean >ftrue : boolean >ff : any +>f : { (): T; g(): U; } >true : true true; @@ -73,8 +115,8 @@ true; // Parsed as instantiation expression const x3 = f; ->x3 : any ->f : any +>x3 : { (): true; g(): U; } +>f : { (): T; g(): U; } >true : true true; diff --git a/tests/baselines/reference/newOperatorErrorCases.errors.txt b/tests/baselines/reference/newOperatorErrorCases.errors.txt index 168fb886f61bf..faa840f4ee012 100644 --- a/tests/baselines/reference/newOperatorErrorCases.errors.txt +++ b/tests/baselines/reference/newOperatorErrorCases.errors.txt @@ -1,10 +1,9 @@ tests/cases/conformance/expressions/newOperator/newOperatorErrorCases.ts(26,16): error TS1005: ',' expected. tests/cases/conformance/expressions/newOperator/newOperatorErrorCases.ts(26,16): error TS2695: Left side of comma operator is unused and has no side effects. -tests/cases/conformance/expressions/newOperator/newOperatorErrorCases.ts(31,9): error TS1384: A 'new' expression with type arguments must always be followed by a parenthesized argument list. tests/cases/conformance/expressions/newOperator/newOperatorErrorCases.ts(36,9): error TS2350: Only a void function can be called with the 'new' keyword. -==== tests/cases/conformance/expressions/newOperator/newOperatorErrorCases.ts (4 errors) ==== +==== tests/cases/conformance/expressions/newOperator/newOperatorErrorCases.ts (3 errors) ==== class C0 { } @@ -39,9 +38,7 @@ tests/cases/conformance/expressions/newOperator/newOperatorErrorCases.ts(36,9): // Generic construct expression with no parentheses var c1 = new T; var c1: T<{}>; - var c2 = new T; // Parse error - ~~~~~~~~~~~~~~ -!!! error TS1384: A 'new' expression with type arguments must always be followed by a parenthesized argument list. + var c2 = new T; // Ok // Construct expression of non-void returning function diff --git a/tests/baselines/reference/newOperatorErrorCases.js b/tests/baselines/reference/newOperatorErrorCases.js index e9292cd20adfa..810503f9f3d16 100644 --- a/tests/baselines/reference/newOperatorErrorCases.js +++ b/tests/baselines/reference/newOperatorErrorCases.js @@ -29,7 +29,7 @@ var b = new C0 32, ''; // Parse error // Generic construct expression with no parentheses var c1 = new T; var c1: T<{}>; -var c2 = new T; // Parse error +var c2 = new T; // Ok // Construct expression of non-void returning function @@ -62,7 +62,7 @@ var b = new C0; // Generic construct expression with no parentheses var c1 = new T; var c1; -var c2 = new T; // Parse error +var c2 = new T; // Ok // Construct expression of non-void returning function function fnNumber() { return 32; } var s = new fnNumber(); // Error diff --git a/tests/baselines/reference/newOperatorErrorCases.symbols b/tests/baselines/reference/newOperatorErrorCases.symbols index 2efbc98fe031c..584b62f0c8567 100644 --- a/tests/baselines/reference/newOperatorErrorCases.symbols +++ b/tests/baselines/reference/newOperatorErrorCases.symbols @@ -58,7 +58,7 @@ var c1: T<{}>; >c1 : Symbol(c1, Decl(newOperatorErrorCases.ts, 28, 3), Decl(newOperatorErrorCases.ts, 29, 3)) >T : Symbol(T, Decl(newOperatorErrorCases.ts, 5, 1)) -var c2 = new T; // Parse error +var c2 = new T; // Ok >c2 : Symbol(c2, Decl(newOperatorErrorCases.ts, 30, 3)) >T : Symbol(T, Decl(newOperatorErrorCases.ts, 5, 1)) diff --git a/tests/baselines/reference/newOperatorErrorCases.types b/tests/baselines/reference/newOperatorErrorCases.types index 0f5cb3622abcb..655baaffd2efd 100644 --- a/tests/baselines/reference/newOperatorErrorCases.types +++ b/tests/baselines/reference/newOperatorErrorCases.types @@ -56,7 +56,7 @@ var c1 = new T; var c1: T<{}>; >c1 : T -var c2 = new T; // Parse error +var c2 = new T; // Ok >c2 : T >new T : T >T : typeof T diff --git a/tests/baselines/reference/parserConstructorAmbiguity3.errors.txt b/tests/baselines/reference/parserConstructorAmbiguity3.errors.txt index 09677fcbb7af1..6725a9db48955 100644 --- a/tests/baselines/reference/parserConstructorAmbiguity3.errors.txt +++ b/tests/baselines/reference/parserConstructorAmbiguity3.errors.txt @@ -1,12 +1,9 @@ -tests/cases/conformance/parser/ecmascript5/Generics/parserConstructorAmbiguity3.ts(1,1): error TS1384: A 'new' expression with type arguments must always be followed by a parenthesized argument list. tests/cases/conformance/parser/ecmascript5/Generics/parserConstructorAmbiguity3.ts(1,10): error TS2304: Cannot find name 'A'. tests/cases/conformance/parser/ecmascript5/Generics/parserConstructorAmbiguity3.ts(1,10): error TS2558: Expected 0 type arguments, but got 1. -==== tests/cases/conformance/parser/ecmascript5/Generics/parserConstructorAmbiguity3.ts (3 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/Generics/parserConstructorAmbiguity3.ts (2 errors) ==== new Date - ~~~~~~~~~~~ -!!! error TS1384: A 'new' expression with type arguments must always be followed by a parenthesized argument list. ~ !!! error TS2304: Cannot find name 'A'. ~ diff --git a/tests/baselines/reference/parserMemberAccessExpression1.errors.txt b/tests/baselines/reference/parserMemberAccessExpression1.errors.txt index 5920aa121956f..f791d4dc1caec 100644 --- a/tests/baselines/reference/parserMemberAccessExpression1.errors.txt +++ b/tests/baselines/reference/parserMemberAccessExpression1.errors.txt @@ -3,15 +3,11 @@ tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(2,1): error TS2304: Cannot find name 'Foo'. tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(2,9): error TS2304: Cannot find name 'T'. tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(3,1): error TS2304: Cannot find name 'Foo'. -tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(3,7): error TS1005: ';' expected. -tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(3,8): error TS2304: Cannot find name 'Bar'. tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(4,1): error TS2304: Cannot find name 'Foo'. -tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(4,7): error TS1005: ';' expected. -tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(4,8): error TS2304: Cannot find name 'Bar'. tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts(4,12): error TS2304: Cannot find name 'T'. -==== tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts (11 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression1.ts (7 errors) ==== Foo(); ~~~ !!! error TS2304: Cannot find name 'Foo'. @@ -25,17 +21,9 @@ tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessExpression Foo.Bar(); ~~~ !!! error TS2304: Cannot find name 'Foo'. - ~ -!!! error TS1005: ';' expected. - ~~~ -!!! error TS2304: Cannot find name 'Bar'. Foo.Bar(); ~~~ !!! error TS2304: Cannot find name 'Foo'. - ~ -!!! error TS1005: ';' expected. - ~~~ -!!! error TS2304: Cannot find name 'Bar'. ~ !!! error TS2304: Cannot find name 'T'. \ No newline at end of file diff --git a/tests/baselines/reference/parserMemberAccessExpression1.js b/tests/baselines/reference/parserMemberAccessExpression1.js index 63ad3a4c7e879..1b3df778063b2 100644 --- a/tests/baselines/reference/parserMemberAccessExpression1.js +++ b/tests/baselines/reference/parserMemberAccessExpression1.js @@ -8,7 +8,5 @@ Foo.Bar(); //// [parserMemberAccessExpression1.js] Foo(); Foo.Bar(); -Foo; -Bar(); -Foo; -Bar(); +Foo.Bar(); +Foo.Bar(); diff --git a/tests/baselines/reference/parserMemberAccessExpression1.types b/tests/baselines/reference/parserMemberAccessExpression1.types index db1c874c84c97..08299f7dfd75f 100644 --- a/tests/baselines/reference/parserMemberAccessExpression1.types +++ b/tests/baselines/reference/parserMemberAccessExpression1.types @@ -10,12 +10,14 @@ Foo.Bar(); >Bar : any Foo.Bar(); +>Foo.Bar() : any +>Foo.Bar : any >Foo : any ->Bar() : any >Bar : any Foo.Bar(); +>Foo.Bar() : any +>Foo.Bar : any >Foo : any ->Bar() : any >Bar : any diff --git a/tests/baselines/reference/parserMemberAccessOffOfGenericType1.errors.txt b/tests/baselines/reference/parserMemberAccessOffOfGenericType1.errors.txt index fe67401732ad5..d0ffa095c3ee7 100644 --- a/tests/baselines/reference/parserMemberAccessOffOfGenericType1.errors.txt +++ b/tests/baselines/reference/parserMemberAccessOffOfGenericType1.errors.txt @@ -1,16 +1,7 @@ tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGenericType1.ts(1,9): error TS2304: Cannot find name 'List'. -tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGenericType1.ts(1,21): error TS1005: ',' expected. -tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGenericType1.ts(1,31): error TS1005: ',' expected. -tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGenericType1.ts(1,32): error TS1109: Expression expected. -==== tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGenericType1.ts (4 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGenericType1.ts (1 errors) ==== var v = List.makeChild(); ~~~~ -!!! error TS2304: Cannot find name 'List'. - ~ -!!! error TS1005: ',' expected. - ~ -!!! error TS1005: ',' expected. - ~ -!!! error TS1109: Expression expected. \ No newline at end of file +!!! error TS2304: Cannot find name 'List'. \ No newline at end of file diff --git a/tests/baselines/reference/parserMemberAccessOffOfGenericType1.js b/tests/baselines/reference/parserMemberAccessOffOfGenericType1.js index eb0a0b94a0594..d73594d4a6d3e 100644 --- a/tests/baselines/reference/parserMemberAccessOffOfGenericType1.js +++ b/tests/baselines/reference/parserMemberAccessOffOfGenericType1.js @@ -2,5 +2,4 @@ var v = List.makeChild(); //// [parserMemberAccessOffOfGenericType1.js] -var v = (List), makeChild; -(); +var v = List.makeChild(); diff --git a/tests/baselines/reference/parserMemberAccessOffOfGenericType1.symbols b/tests/baselines/reference/parserMemberAccessOffOfGenericType1.symbols index 5813f78e326af..ab2eff6445126 100644 --- a/tests/baselines/reference/parserMemberAccessOffOfGenericType1.symbols +++ b/tests/baselines/reference/parserMemberAccessOffOfGenericType1.symbols @@ -1,5 +1,4 @@ === tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGenericType1.ts === var v = List.makeChild(); >v : Symbol(v, Decl(parserMemberAccessOffOfGenericType1.ts, 0, 3)) ->makeChild : Symbol(makeChild, Decl(parserMemberAccessOffOfGenericType1.ts, 0, 21)) diff --git a/tests/baselines/reference/parserMemberAccessOffOfGenericType1.types b/tests/baselines/reference/parserMemberAccessOffOfGenericType1.types index 2b73261a99e46..2bd59381f8765 100644 --- a/tests/baselines/reference/parserMemberAccessOffOfGenericType1.types +++ b/tests/baselines/reference/parserMemberAccessOffOfGenericType1.types @@ -1,8 +1,8 @@ === tests/cases/conformance/parser/ecmascript5/Generics/parserMemberAccessOffOfGenericType1.ts === var v = List.makeChild(); >v : any +>List.makeChild() : any +>List.makeChild : any >List : any >makeChild : any ->() : any -> : any diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.errors.txt b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.errors.txt index 1ee7243beaa47..d71231547302d 100644 --- a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.errors.txt +++ b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.errors.txt @@ -1,14 +1,13 @@ tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(13,30): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(15,11): error TS2347: Untyped function calls may not accept type arguments. -tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(17,11): error TS2347: Untyped function calls may not accept type arguments. tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(17,30): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. +tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(17,59): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(35,5): error TS2377: Constructors for derived classes must contain a 'super' call. tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(36,9): error TS17011: 'super' must be called before accessing a property of 'super' in the constructor of a derived class. tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(36,14): error TS2754: 'super' may not use type arguments. tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(36,34): error TS1034: 'super' must be followed by an argument list or member access. -==== tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts (8 errors) ==== +==== tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts (7 errors) ==== export interface SomethingTaggable { (t: TemplateStringsArray, ...args: T[]): SomethingNewable; } @@ -26,14 +25,12 @@ tests/cases/conformance/es6/templates/taggedTemplatesWithTypeArguments2.ts(36,34 !!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. const c = new tag `${100} ${200}`("hello", "world"); - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2347: Untyped function calls may not accept type arguments. const d = new tag `${"hello"} ${"world"}`(100, 200); - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2347: Untyped function calls may not accept type arguments. ~~~~~~~ !!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. + ~~~ +!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. /** * Testing ASI. This should never parse as diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.js b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.js index 6ab9b7afa1d9f..7e055f817b2ba 100644 --- a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.js +++ b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.js @@ -41,8 +41,8 @@ class SomeDerived extends SomeBase { //// [taggedTemplatesWithTypeArguments2.js] const a = new tag `${100} ${200}`("hello", "world"); const b = new tag `${"hello"} ${"world"}`(100, 200); -const c = (new tag `${100} ${200}`)("hello", "world"); -const d = (new tag `${"hello"} ${"world"}`)(100, 200); +const c = new tag `${100} ${200}`("hello", "world"); +const d = new tag `${"hello"} ${"world"}`(100, 200); /** * Testing ASI. This should never parse as * diff --git a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.types b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.types index c78719846cf72..036dc7e6de167 100644 --- a/tests/baselines/reference/taggedTemplatesWithTypeArguments2.types +++ b/tests/baselines/reference/taggedTemplatesWithTypeArguments2.types @@ -38,7 +38,6 @@ const b = new tag `${"hello"} ${"world"}`(100, 200); const c = new tag `${100} ${200}`("hello", "world"); >c : any >new tag `${100} ${200}`("hello", "world") : any ->new tag `${100} ${200}` : any >tag `${100} ${200}` : SomethingNewable >tag : SomethingTaggable >`${100} ${200}` : string @@ -50,7 +49,6 @@ const c = new tag `${100} ${200}`("hello", "world"); const d = new tag `${"hello"} ${"world"}`(100, 200); >d : any >new tag `${"hello"} ${"world"}`(100, 200) : any ->new tag `${"hello"} ${"world"}` : any >tag `${"hello"} ${"world"}` : SomethingNewable >tag : SomethingTaggable >`${"hello"} ${"world"}` : string