diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3fc27bd4f34f2..52e56344b00b4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3816,6 +3816,23 @@ namespace ts { members, callSignatures, constructSignatures, stringIndexInfo, numberIndexInfo); } + function getResolvedTypeWithoutAbstractConstructSignatures(type: ResolvedType) { + if (type.constructSignatures.length === 0) return type; + if (type.objectTypeWithoutAbstractConstructSignatures) return type.objectTypeWithoutAbstractConstructSignatures; + const constructSignatures = filter(type.constructSignatures, signature => !(signature.flags & SignatureFlags.Abstract)); + if (type.constructSignatures === constructSignatures) return type; + const typeCopy = createAnonymousType( + type.symbol, + type.members, + type.callSignatures, + some(constructSignatures) ? constructSignatures : emptyArray, + type.stringIndexInfo, + type.numberIndexInfo); + type.objectTypeWithoutAbstractConstructSignatures = typeCopy; + typeCopy.objectTypeWithoutAbstractConstructSignatures = typeCopy; + return typeCopy; + } + function forEachSymbolTableInScope(enclosingDeclaration: Node | undefined, callback: (symbolTable: SymbolTable) => T): T { let result: T; for (let location = enclosingDeclaration; location; location = location.parent) { @@ -4762,13 +4779,38 @@ namespace ts { } } + const abstractSignatures = filter(resolved.constructSignatures, signature => !!(signature.flags & SignatureFlags.Abstract)); + if (some(abstractSignatures)) { + const types = map(abstractSignatures, getOrCreateTypeFromSignature); + // count the number of type elements excluding abstract constructors + const typeElementCount = + resolved.callSignatures.length + + (resolved.constructSignatures.length - abstractSignatures.length) + + (resolved.stringIndexInfo ? 1 : 0) + + (resolved.numberIndexInfo ? 1 : 0) + + // exclude `prototype` when writing a class expression as a type literal, as per + // the logic in `createTypeNodesFromResolvedType`. + (context.flags & NodeBuilderFlags.WriteClassExpressionAsTypeLiteral ? + countWhere(resolved.properties, p => !(p.flags & SymbolFlags.Prototype)) : + length(resolved.properties)); + // don't include an empty object literal if there were no other static-side + // properties to write, i.e. `abstract class C { }` becomes `abstract new () => {}` + // and not `(abstract new () => {}) & {}` + if (typeElementCount) { + // create a copy of the object type without any abstract construct signatures. + types.push(getResolvedTypeWithoutAbstractConstructSignatures(resolved)); + } + return typeToTypeNodeHelper(getIntersectionType(types), context); + } + const savedFlags = context.flags; context.flags |= NodeBuilderFlags.InObjectTypeLiteral; const members = createTypeNodesFromResolvedType(resolved); context.flags = savedFlags; const typeLiteralNode = factory.createTypeLiteralNode(members); context.approximateLength += 2; - return setEmitFlags(typeLiteralNode, (context.flags & NodeBuilderFlags.MultilineObjectLiterals) ? 0 : EmitFlags.SingleLine); + setEmitFlags(typeLiteralNode, (context.flags & NodeBuilderFlags.MultilineObjectLiterals) ? 0 : EmitFlags.SingleLine); + return typeLiteralNode; } function typeReferenceToTypeNode(type: TypeReference) { @@ -4938,6 +4980,7 @@ namespace ts { typeElements.push(signatureToSignatureDeclarationHelper(signature, SyntaxKind.CallSignature, context)); } for (const signature of resolvedType.constructSignatures) { + if (signature.flags & SignatureFlags.Abstract) continue; typeElements.push(signatureToSignatureDeclarationHelper(signature, SyntaxKind.ConstructSignature, context)); } if (resolvedType.stringIndexInfo) { @@ -5210,23 +5253,28 @@ namespace ts { returnTypeNode = factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); } } + let modifiers = options?.modifiers; + if ((kind === SyntaxKind.ConstructorType) && signature.flags & SignatureFlags.Abstract) { + const flags = modifiersToFlags(modifiers); + modifiers = factory.createModifiersFromModifierFlags(flags | ModifierFlags.Abstract); + } context.approximateLength += 3; // Usually a signature contributes a few more characters than this, but 3 is the minimum const node = kind === SyntaxKind.CallSignature ? factory.createCallSignature(typeParameters, parameters, returnTypeNode) : kind === SyntaxKind.ConstructSignature ? factory.createConstructSignature(typeParameters, parameters, returnTypeNode) : - kind === SyntaxKind.MethodSignature ? factory.createMethodSignature(options?.modifiers, options?.name ?? factory.createIdentifier(""), options?.questionToken, typeParameters, parameters, returnTypeNode) : - kind === SyntaxKind.MethodDeclaration ? factory.createMethodDeclaration(/*decorators*/ undefined, options?.modifiers, /*asteriskToken*/ undefined, options?.name ?? factory.createIdentifier(""), /*questionToken*/ undefined, typeParameters, parameters, returnTypeNode, /*body*/ undefined) : - kind === SyntaxKind.Constructor ? factory.createConstructorDeclaration(/*decorators*/ undefined, options?.modifiers, parameters, /*body*/ undefined) : - kind === SyntaxKind.GetAccessor ? factory.createGetAccessorDeclaration(/*decorators*/ undefined, options?.modifiers, options?.name ?? factory.createIdentifier(""), parameters, returnTypeNode, /*body*/ undefined) : - kind === SyntaxKind.SetAccessor ? factory.createSetAccessorDeclaration(/*decorators*/ undefined, options?.modifiers, options?.name ?? factory.createIdentifier(""), parameters, /*body*/ undefined) : - kind === SyntaxKind.IndexSignature ? factory.createIndexSignature(/*decorators*/ undefined, options?.modifiers, parameters, returnTypeNode) : + kind === SyntaxKind.MethodSignature ? factory.createMethodSignature(modifiers, options?.name ?? factory.createIdentifier(""), options?.questionToken, typeParameters, parameters, returnTypeNode) : + kind === SyntaxKind.MethodDeclaration ? factory.createMethodDeclaration(/*decorators*/ undefined, modifiers, /*asteriskToken*/ undefined, options?.name ?? factory.createIdentifier(""), /*questionToken*/ undefined, typeParameters, parameters, returnTypeNode, /*body*/ undefined) : + kind === SyntaxKind.Constructor ? factory.createConstructorDeclaration(/*decorators*/ undefined, modifiers, parameters, /*body*/ undefined) : + kind === SyntaxKind.GetAccessor ? factory.createGetAccessorDeclaration(/*decorators*/ undefined, modifiers, options?.name ?? factory.createIdentifier(""), parameters, returnTypeNode, /*body*/ undefined) : + kind === SyntaxKind.SetAccessor ? factory.createSetAccessorDeclaration(/*decorators*/ undefined, modifiers, options?.name ?? factory.createIdentifier(""), parameters, /*body*/ undefined) : + kind === SyntaxKind.IndexSignature ? factory.createIndexSignature(/*decorators*/ undefined, modifiers, parameters, returnTypeNode) : kind === SyntaxKind.JSDocFunctionType ? factory.createJSDocFunctionType(parameters, returnTypeNode) : kind === SyntaxKind.FunctionType ? factory.createFunctionTypeNode(typeParameters, parameters, returnTypeNode ?? factory.createTypeReferenceNode(factory.createIdentifier(""))) : - kind === SyntaxKind.ConstructorType ? factory.createConstructorTypeNode(typeParameters, parameters, returnTypeNode ?? factory.createTypeReferenceNode(factory.createIdentifier(""))) : - kind === SyntaxKind.FunctionDeclaration ? factory.createFunctionDeclaration(/*decorators*/ undefined, options?.modifiers, /*asteriskToken*/ undefined, options?.name ? cast(options.name, isIdentifier) : factory.createIdentifier(""), typeParameters, parameters, returnTypeNode, /*body*/ undefined) : - kind === SyntaxKind.FunctionExpression ? factory.createFunctionExpression(options?.modifiers, /*asteriskToken*/ undefined, options?.name ? cast(options.name, isIdentifier) : factory.createIdentifier(""), typeParameters, parameters, returnTypeNode, factory.createBlock([])) : - kind === SyntaxKind.ArrowFunction ? factory.createArrowFunction(options?.modifiers, typeParameters, parameters, returnTypeNode, /*equalsGreaterThanToken*/ undefined, factory.createBlock([])) : + kind === SyntaxKind.ConstructorType ? factory.createConstructorTypeNode(modifiers, typeParameters, parameters, returnTypeNode ?? factory.createTypeReferenceNode(factory.createIdentifier(""))) : + kind === SyntaxKind.FunctionDeclaration ? factory.createFunctionDeclaration(/*decorators*/ undefined, modifiers, /*asteriskToken*/ undefined, options?.name ? cast(options.name, isIdentifier) : factory.createIdentifier(""), typeParameters, parameters, returnTypeNode, /*body*/ undefined) : + kind === SyntaxKind.FunctionExpression ? factory.createFunctionExpression(modifiers, /*asteriskToken*/ undefined, options?.name ? cast(options.name, isIdentifier) : factory.createIdentifier(""), typeParameters, parameters, returnTypeNode, factory.createBlock([])) : + kind === SyntaxKind.ArrowFunction ? factory.createArrowFunction(modifiers, typeParameters, parameters, returnTypeNode, /*equalsGreaterThanToken*/ undefined, factory.createBlock([])) : Debug.assertNever(kind); if (typeArguments) { @@ -5958,6 +6006,7 @@ namespace ts { if (isJSDocConstructSignature(node)) { let newTypeNode: TypeNode | undefined; return factory.createConstructorTypeNode( + node.modifiers, visitNodes(node.typeParameters, visitExistingNodeTreeSymbols), mapDefined(node.parameters, (p, i) => p.name && isIdentifier(p.name) && p.name.escapedText === "new" ? (newTypeNode = p.type, undefined) : factory.createParameterDeclaration( /*decorators*/ undefined, @@ -9158,7 +9207,10 @@ namespace ts { const signatures = getSignaturesOfType(type, SignatureKind.Construct); if (signatures.length === 1) { const s = signatures[0]; - return !s.typeParameters && s.parameters.length === 1 && signatureHasRestParameter(s) && getElementTypeOfArrayType(getTypeOfParameter(s.parameters[0])) === anyType; + if (!s.typeParameters && s.parameters.length === 1 && signatureHasRestParameter(s)) { + const paramType = getTypeOfParameter(s.parameters[0]); + return isTypeAny(paramType) || getElementTypeOfArrayType(paramType) === anyType; + } } return false; } @@ -10178,8 +10230,10 @@ namespace ts { function getDefaultConstructSignatures(classType: InterfaceType): Signature[] { const baseConstructorType = getBaseConstructorTypeOfClass(classType); const baseSignatures = getSignaturesOfType(baseConstructorType, SignatureKind.Construct); + const declaration = getClassLikeDeclarationOfSymbol(classType.symbol); + const isAbstract = !!declaration && hasSyntacticModifier(declaration, ModifierFlags.Abstract); if (baseSignatures.length === 0) { - return [createSignature(undefined, classType.localTypeParameters, undefined, emptyArray, classType, /*resolvedTypePredicate*/ undefined, 0, SignatureFlags.None)]; + return [createSignature(undefined, classType.localTypeParameters, undefined, emptyArray, classType, /*resolvedTypePredicate*/ undefined, 0, isAbstract ? SignatureFlags.Abstract : SignatureFlags.None)]; } const baseTypeNode = getBaseTypeNodeOfClass(classType)!; const isJavaScript = isInJSFile(baseTypeNode); @@ -10193,6 +10247,7 @@ namespace ts { const sig = typeParamCount ? createSignatureInstantiation(baseSig, fillMissingTypeArguments(typeArguments, baseSig.typeParameters, minTypeArgumentCount, isJavaScript)) : cloneSignature(baseSig); sig.typeParameters = classType.localTypeParameters; sig.resolvedReturnType = classType; + sig.flags = isAbstract ? sig.flags | SignatureFlags.Abstract : sig.flags & ~SignatureFlags.Abstract; result.push(sig); } } @@ -11766,6 +11821,10 @@ namespace ts { if (hasRestParameter(declaration) || isInJSFile(declaration) && maybeAddJsSyntheticRestParameter(declaration, parameters)) { flags |= SignatureFlags.HasRestParameter; } + if (isConstructorTypeNode(declaration) && hasSyntacticModifier(declaration, ModifierFlags.Abstract) || + isConstructorDeclaration(declaration) && hasSyntacticModifier(declaration.parent, ModifierFlags.Abstract)) { + flags |= SignatureFlags.Abstract; + } links.resolvedSignature = createSignature(declaration, typeParameters, thisParameter, parameters, /*resolvedReturnType*/ undefined, /*resolvedTypePredicate*/ undefined, minArgumentCount, flags); @@ -18433,7 +18492,9 @@ namespace ts { SignatureKind.Call : kind); if (kind === SignatureKind.Construct && sourceSignatures.length && targetSignatures.length) { - if (isAbstractConstructorType(source) && !isAbstractConstructorType(target)) { + const sourceIsAbstract = !!(sourceSignatures[0].flags & SignatureFlags.Abstract); + const targetIsAbstract = !!(targetSignatures[0].flags & SignatureFlags.Abstract); + if (sourceIsAbstract && !targetIsAbstract) { // An abstract constructor type is not assignable to a non-abstract constructor type // as it would otherwise be possible to new an abstract class. Note that the assignability // check we perform for an extends clause excludes construct signatures from the target, @@ -28031,10 +28092,14 @@ namespace ts { if (!isConstructorAccessible(node, constructSignatures[0])) { return resolveErrorCall(node); } - // If the expression is a class of abstract type, then it cannot be instantiated. - // Note, only class declarations can be declared abstract. + // If the expression is a class of abstract type, or an abstract construct signature, + // then it cannot be instantiated. // In the case of a merged class-module or class-interface declaration, // only the class declaration node will have the Abstract flag set. + if (constructSignatures.some(signature => signature.flags & SignatureFlags.Abstract)) { + error(node, Diagnostics.Cannot_create_an_instance_of_an_abstract_class); + return resolveErrorCall(node); + } const valueDecl = expressionType.symbol && getClassLikeDeclarationOfSymbol(expressionType.symbol); if (valueDecl && hasSyntacticModifier(valueDecl, ModifierFlags.Abstract)) { error(node, Diagnostics.Cannot_create_an_instance_of_an_abstract_class); @@ -32340,7 +32405,6 @@ namespace ts { const someButNotAllOverloadFlags = someOverloadFlags ^ allOverloadFlags; if (someButNotAllOverloadFlags !== 0) { const canonicalFlags = getEffectiveDeclarationFlags(getCanonicalOverload(overloads, implementation), flagsToCheck); - forEach(overloads, o => { const deviation = getEffectiveDeclarationFlags(o, flagsToCheck) ^ canonicalFlags; if (deviation & ModifierFlags.Export) { @@ -35641,8 +35705,16 @@ namespace ts { checkTypeAssignableTo(staticType, getTypeWithoutSignatures(staticBaseType), node.name || node, Diagnostics.Class_static_side_0_incorrectly_extends_base_class_static_side_1); } - if (baseConstructorType.flags & TypeFlags.TypeVariable && !isMixinConstructorType(staticType)) { - error(node.name || node, Diagnostics.A_mixin_class_must_have_a_constructor_with_a_single_rest_parameter_of_type_any); + if (baseConstructorType.flags & TypeFlags.TypeVariable) { + if (!isMixinConstructorType(staticType)) { + error(node.name || node, Diagnostics.A_mixin_class_must_have_a_constructor_with_a_single_rest_parameter_of_type_any); + } + else { + const constructSignatures = getSignaturesOfType(baseConstructorType, SignatureKind.Construct); + if (constructSignatures.some(signature => signature.flags & SignatureFlags.Abstract) && !hasSyntacticModifier(node, ModifierFlags.Abstract)) { + error(node.name || node, Diagnostics.A_mixin_class_that_extends_from_a_type_variable_containing_an_abstract_construct_signature_must_also_be_declared_abstract); + } + } } if (!(staticBaseType.symbol && staticBaseType.symbol.flags & SymbolFlags.Class) && !(baseConstructorType.flags & TypeFlags.TypeVariable)) { @@ -36922,8 +36994,8 @@ namespace ts { return checkPropertyDeclaration(node); case SyntaxKind.PropertySignature: return checkPropertySignature(node); - case SyntaxKind.FunctionType: case SyntaxKind.ConstructorType: + case SyntaxKind.FunctionType: case SyntaxKind.CallSignature: case SyntaxKind.ConstructSignature: case SyntaxKind.IndexSignature: @@ -39194,7 +39266,8 @@ namespace ts { if (flags & ModifierFlags.Abstract) { return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "abstract"); } - if (node.kind !== SyntaxKind.ClassDeclaration) { + if (node.kind !== SyntaxKind.ClassDeclaration && + node.kind !== SyntaxKind.ConstructorType) { if (node.kind !== SyntaxKind.MethodDeclaration && node.kind !== SyntaxKind.PropertyDeclaration && node.kind !== SyntaxKind.GetAccessor && @@ -39308,6 +39381,7 @@ namespace ts { case SyntaxKind.FunctionDeclaration: return nodeHasAnyModifiersExcept(node, SyntaxKind.AsyncKeyword); case SyntaxKind.ClassDeclaration: + case SyntaxKind.ConstructorType: return nodeHasAnyModifiersExcept(node, SyntaxKind.AbstractKeyword); case SyntaxKind.InterfaceDeclaration: case SyntaxKind.VariableStatement: @@ -39317,7 +39391,6 @@ namespace ts { return nodeHasAnyModifiersExcept(node, SyntaxKind.ConstKeyword); default: Debug.fail(); - return false; } } } diff --git a/src/compiler/debug.ts b/src/compiler/debug.ts index 8e3ce1cfa46c9..8d14c9c1ee5d7 100644 --- a/src/compiler/debug.ts +++ b/src/compiler/debug.ts @@ -367,6 +367,10 @@ namespace ts { return formatEnum(flags, (ts).TypeFlags, /*isFlags*/ true); } + export function formatSignatureFlags(flags: SignatureFlags | undefined): string { + return formatEnum(flags, (ts).SignatureFlags, /*isFlags*/ true); + } + export function formatObjectFlags(flags: ObjectFlags | undefined): string { return formatEnum(flags, (ts).ObjectFlags, /*isFlags*/ true); } @@ -573,6 +577,11 @@ namespace ts { }, }); + Object.defineProperties(objectAllocator.getSignatureConstructor().prototype, { + __debugFlags: { get(this: Signature) { return formatSignatureFlags(this.flags); } }, + __debugSignatureToString: { value(this: Signature) { return this.checker?.signatureToString(this); } } + }); + const nodeConstructors = [ objectAllocator.getNodeConstructor(), objectAllocator.getIdentifierConstructor(), diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 37f12224c75fa..634d872c7883a 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -3211,6 +3211,10 @@ "category": "Error", "code": 2796 }, + "A mixin class that extends from a type variable containing an abstract construct signature must also be declared 'abstract'.": { + "category": "Error", + "code": 2797 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 5fb7e97863e6a..8d495dfebda0f 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -2131,6 +2131,7 @@ namespace ts { function emitConstructorType(node: ConstructorTypeNode) { pushNameGenerationScope(node); + emitModifiers(node, node.modifiers); writeKeyword("new"); writeSpace(); emitTypeParameters(node, node.typeParameters); diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index 176c9154dcd38..5f3a19a8949ac 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -1700,7 +1700,14 @@ namespace ts { } // @api - function createConstructorTypeNode( + function createConstructorTypeNode(...args: Parameters) { + return args.length === 4 ? createConstructorTypeNode1(...args) : + args.length === 3 ? createConstructorTypeNode2(...args) : + Debug.fail("Incorrect number of arguments specified."); + } + + function createConstructorTypeNode1( + modifiers: readonly Modifier[] | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode | undefined @@ -1708,7 +1715,7 @@ namespace ts { const node = createBaseSignatureDeclaration( SyntaxKind.ConstructorType, /*decorators*/ undefined, - /*modifiers*/ undefined, + modifiers, /*name*/ undefined, typeParameters, parameters, @@ -1718,20 +1725,47 @@ namespace ts { return node; } + /** @deprecated */ + function createConstructorTypeNode2( + typeParameters: readonly TypeParameterDeclaration[] | undefined, + parameters: readonly ParameterDeclaration[], + type: TypeNode | undefined + ): ConstructorTypeNode { + return createConstructorTypeNode1(/*modifiers*/ undefined, typeParameters, parameters, type); + } + // @api - function updateConstructorTypeNode( + function updateConstructorTypeNode(...args: Parameters) { + return args.length === 5 ? updateConstructorTypeNode1(...args) : + args.length === 4 ? updateConstructorTypeNode2(...args) : + Debug.fail("Incorrect number of arguments specified."); + } + + function updateConstructorTypeNode1( node: ConstructorTypeNode, + modifiers: readonly Modifier[] | undefined, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode | undefined ) { - return node.typeParameters !== typeParameters + return node.modifiers !== modifiers + || node.typeParameters !== typeParameters || node.parameters !== parameters || node.type !== type - ? updateBaseSignatureDeclaration(createConstructorTypeNode(typeParameters, parameters, type), node) + ? updateBaseSignatureDeclaration(createConstructorTypeNode(modifiers, typeParameters, parameters, type), node) : node; } + /** @deprecated */ + function updateConstructorTypeNode2( + node: ConstructorTypeNode, + typeParameters: NodeArray | undefined, + parameters: NodeArray, + type: TypeNode | undefined + ) { + return updateConstructorTypeNode1(node, node.modifiers, typeParameters, parameters, type); + } + // @api function createTypeQueryNode(exprName: EntityName) { const node = createBaseNode(SyntaxKind.TypeQuery); diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index b3ae9b9f7b638..6e6f1dcc19777 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -3368,16 +3368,29 @@ namespace ts { return finishNode(factory.createParenthesizedType(type), pos); } + function parseModifiersForConstructorType(): NodeArray | undefined { + let modifiers: NodeArray | undefined; + if (token() === SyntaxKind.AbstractKeyword) { + const pos = getNodePos(); + nextToken(); + const modifier = finishNode(factory.createToken(SyntaxKind.AbstractKeyword), pos); + modifiers = createNodeArray([modifier], pos); + } + return modifiers; + } + function parseFunctionOrConstructorType(): TypeNode { const pos = getNodePos(); const hasJSDoc = hasPrecedingJSDocComment(); + const modifiers = parseModifiersForConstructorType(); const isConstructorType = parseOptional(SyntaxKind.NewKeyword); const typeParameters = parseTypeParameters(); const parameters = parseParameters(SignatureFlags.Type); const type = parseReturnType(SyntaxKind.EqualsGreaterThanToken, /*isType*/ false); const node = isConstructorType - ? factory.createConstructorTypeNode(typeParameters, parameters, type) + ? factory.createConstructorTypeNode(modifiers, typeParameters, parameters, type) : factory.createFunctionTypeNode(typeParameters, parameters, type); + if (!isConstructorType) (node as Mutable).modifiers = modifiers; return withJSDoc(finishNode(node, pos), hasJSDoc); } @@ -3678,6 +3691,11 @@ namespace ts { return parseUnionOrIntersectionType(SyntaxKind.BarToken, parseIntersectionTypeOrHigher, factory.createUnionTypeNode); } + function nextTokenIsNewKeyword(): boolean { + nextToken(); + return token() === SyntaxKind.NewKeyword; + } + function isStartOfFunctionTypeOrConstructorType(): boolean { if (token() === SyntaxKind.LessThanToken) { return true; @@ -3685,7 +3703,8 @@ namespace ts { if (token() === SyntaxKind.OpenParenToken && lookAhead(isUnambiguouslyStartOfFunctionType)) { return true; } - return token() === SyntaxKind.NewKeyword; + return token() === SyntaxKind.NewKeyword || + token() === SyntaxKind.AbstractKeyword && lookAhead(nextTokenIsNewKeyword); } function skipParameterStart(): boolean { diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 1fc500d2da81e..0ca8840059801 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -1017,7 +1017,7 @@ namespace ts { return cleanup(factory.updateFunctionTypeNode(input, visitNodes(input.typeParameters, visitDeclarationSubtree), updateParamsList(input, input.parameters), visitNode(input.type, visitDeclarationSubtree))); } case SyntaxKind.ConstructorType: { - return cleanup(factory.updateConstructorTypeNode(input, visitNodes(input.typeParameters, visitDeclarationSubtree), updateParamsList(input, input.parameters), visitNode(input.type, visitDeclarationSubtree))); + return cleanup(factory.updateConstructorTypeNode(input, ensureModifiers(input), visitNodes(input.typeParameters, visitDeclarationSubtree), updateParamsList(input, input.parameters), visitNode(input.type, visitDeclarationSubtree))); } case SyntaxKind.ImportType: { if (!isLiteralImportTypeNode(input)) return cleanup(input); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 0dfc911a62323..70462b19ed186 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5172,6 +5172,7 @@ namespace ts { /* @internal */ constructSignatures?: readonly Signature[]; // Construct signatures of type /* @internal */ stringIndexInfo?: IndexInfo; // String indexing info /* @internal */ numberIndexInfo?: IndexInfo; // Numeric indexing info + /* @internal */ objectTypeWithoutAbstractConstructSignatures?: ObjectType; } /** Class and interface types (ObjectFlags.Class and ObjectFlags.Interface). */ @@ -5502,16 +5503,21 @@ namespace ts { /* @internal */ export const enum SignatureFlags { None = 0, + + // Propagating flags HasRestParameter = 1 << 0, // Indicates last parameter is rest parameter HasLiteralTypes = 1 << 1, // Indicates signature is specialized - IsInnerCallChain = 1 << 2, // Indicates signature comes from a CallChain nested in an outer OptionalChain - IsOuterCallChain = 1 << 3, // Indicates signature comes from a CallChain that is the outermost chain of an optional expression - IsUntypedSignatureInJSFile = 1 << 4, // Indicates signature is from a js file and has no types + Abstract = 1 << 2, // Indicates signature comes from an abstract class, abstract construct signature, or abstract constructor type + + // Non-propagating flags + IsInnerCallChain = 1 << 3, // Indicates signature comes from a CallChain nested in an outer OptionalChain + IsOuterCallChain = 1 << 4, // Indicates signature comes from a CallChain that is the outermost chain of an optional expression + IsUntypedSignatureInJSFile = 1 << 5, // Indicates signature is from a js file and has no types - // We do not propagate `IsInnerCallChain` to instantiated signatures, as that would result in us + // We do not propagate `IsInnerCallChain` or `IsOuterCallChain` to instantiated signatures, as that would result in us // attempting to add `| undefined` on each recursive call to `getReturnTypeOfSignature` when // instantiating the return type. - PropagatingFlags = HasRestParameter | HasLiteralTypes | IsUntypedSignatureInJSFile, + PropagatingFlags = HasRestParameter | HasLiteralTypes | Abstract | IsUntypedSignatureInJSFile, CallChainFlags = IsInnerCallChain | IsOuterCallChain, } @@ -6878,7 +6884,11 @@ namespace ts { updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray | undefined): TypeReferenceNode; createFunctionTypeNode(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): FunctionTypeNode; updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode): FunctionTypeNode; + createConstructorTypeNode(modifiers: readonly Modifier[] | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): ConstructorTypeNode; + /** @deprecated */ createConstructorTypeNode(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): ConstructorTypeNode; + 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; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 476a73f55c07a..bd3126f05d173 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -4751,7 +4751,7 @@ namespace ts { return flags; } - export function modifiersToFlags(modifiers: NodeArray | undefined) { + export function modifiersToFlags(modifiers: readonly Modifier[] | undefined) { let flags = ModifierFlags.None; if (modifiers) { for (const modifier of modifiers) { @@ -5452,11 +5452,6 @@ namespace ts { }); } - // Return true if the given type is the constructor type for an abstract class - export function isAbstractConstructorType(type: Type): boolean { - return !!(getObjectFlags(type) & ObjectFlags.Anonymous) && !!type.symbol && isAbstractConstructorSymbol(type.symbol); - } - export function isAbstractConstructorSymbol(symbol: Symbol): boolean { if (symbol.flags & SymbolFlags.Class) { const declaration = getClassLikeDeclarationOfSymbol(symbol); diff --git a/src/compiler/visitorPublic.ts b/src/compiler/visitorPublic.ts index 023361d7cc569..958b7b1bdd511 100644 --- a/src/compiler/visitorPublic.ts +++ b/src/compiler/visitorPublic.ts @@ -485,6 +485,7 @@ namespace ts { case SyntaxKind.ConstructorType: return factory.updateConstructorTypeNode(node, + nodesVisitor((node).modifiers, visitor, isModifier), nodesVisitor((node).typeParameters, visitor, isTypeParameterDeclaration), nodesVisitor((node).parameters, visitor, isParameterDeclaration), nodeVisitor((node).type, visitor, isTypeNode)); diff --git a/src/deprecatedCompat/deprecations.ts b/src/deprecatedCompat/deprecations.ts index 0cce82192df39..b0573ad4ab75d 100644 --- a/src/deprecatedCompat/deprecations.ts +++ b/src/deprecatedCompat/deprecations.ts @@ -164,10 +164,23 @@ namespace ts { export const updateFunctionTypeNode = Debug.deprecate(factory.updateFunctionTypeNode, factoryDeprecation); /** @deprecated Use `factory.createConstructorTypeNode` or the factory supplied by your transformation context instead. */ - export const createConstructorTypeNode = Debug.deprecate(factory.createConstructorTypeNode, factoryDeprecation); + export const createConstructorTypeNode = Debug.deprecate(( + typeParameters: readonly TypeParameterDeclaration[] | undefined, + parameters: readonly ParameterDeclaration[], + type: TypeNode + ) => { + return factory.createConstructorTypeNode(/*modifiers*/ undefined, typeParameters, parameters, type); + }, factoryDeprecation); /** @deprecated Use `factory.updateConstructorTypeNode` or the factory supplied by your transformation context instead. */ - export const updateConstructorTypeNode = Debug.deprecate(factory.updateConstructorTypeNode, factoryDeprecation); + export const updateConstructorTypeNode = Debug.deprecate(( + node: ConstructorTypeNode, + typeParameters: NodeArray | undefined, + parameters: NodeArray, + type: TypeNode + ) => { + return factory.updateConstructorTypeNode(node, node.modifiers, typeParameters, parameters, type); + }, factoryDeprecation); /** @deprecated Use `factory.createTypeQueryNode` or the factory supplied by your transformation context instead. */ export const createTypeQueryNode = Debug.deprecate(factory.createTypeQueryNode, factoryDeprecation); diff --git a/src/services/symbolDisplay.ts b/src/services/symbolDisplay.ts index b1f7480063529..19bfaba4499ef 100644 --- a/src/services/symbolDisplay.ts +++ b/src/services/symbolDisplay.ts @@ -220,6 +220,10 @@ namespace ts.SymbolDisplay { pushSymbolKind(symbolKind); displayParts.push(spacePart()); if (useConstructSignatures) { + if (signature.flags & SignatureFlags.Abstract) { + displayParts.push(keywordPart(SyntaxKind.AbstractKeyword)); + displayParts.push(spacePart()); + } displayParts.push(keywordPart(SyntaxKind.NewKeyword)); displayParts.push(spacePart()); } @@ -245,6 +249,10 @@ namespace ts.SymbolDisplay { displayParts.push(lineBreakPart()); } if (useConstructSignatures) { + if (signature.flags & SignatureFlags.Abstract) { + displayParts.push(keywordPart(SyntaxKind.AbstractKeyword)); + displayParts.push(spacePart()); + } displayParts.push(keywordPart(SyntaxKind.NewKeyword)); displayParts.push(spacePart()); } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index f2795baa971fd..166df79934874 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -3231,7 +3231,11 @@ declare namespace ts { updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray | undefined): TypeReferenceNode; createFunctionTypeNode(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): FunctionTypeNode; updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode): FunctionTypeNode; + createConstructorTypeNode(modifiers: readonly Modifier[] | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): ConstructorTypeNode; + /** @deprecated */ createConstructorTypeNode(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): ConstructorTypeNode; + 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; @@ -10519,9 +10523,9 @@ declare namespace ts { /** @deprecated Use `factory.updateEnumDeclaration` or the factory supplied by your transformation context instead. */ const updateEnumDeclaration: (node: EnumDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, members: readonly EnumMember[]) => EnumDeclaration; /** @deprecated Use `factory.createModuleDeclaration` or the factory supplied by your transformation context instead. */ - const createModuleDeclaration: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: ModuleName, body: Identifier | ModuleBlock | NamespaceDeclaration | JSDocNamespaceDeclaration | undefined, flags?: NodeFlags | undefined) => ModuleDeclaration; + const createModuleDeclaration: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: ModuleName, body: ModuleBlock | NamespaceDeclaration | Identifier | JSDocNamespaceDeclaration | undefined, flags?: NodeFlags | undefined) => ModuleDeclaration; /** @deprecated Use `factory.updateModuleDeclaration` or the factory supplied by your transformation context instead. */ - const updateModuleDeclaration: (node: ModuleDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: ModuleName, body: Identifier | ModuleBlock | NamespaceDeclaration | JSDocNamespaceDeclaration | undefined) => ModuleDeclaration; + const updateModuleDeclaration: (node: ModuleDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: ModuleName, body: ModuleBlock | NamespaceDeclaration | Identifier | JSDocNamespaceDeclaration | undefined) => ModuleDeclaration; /** @deprecated Use `factory.createModuleBlock` or the factory supplied by your transformation context instead. */ const createModuleBlock: (statements: readonly Statement[]) => ModuleBlock; /** @deprecated Use `factory.updateModuleBlock` 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 0f9c37e24b4ce..2da4b0f6e72a7 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -3231,7 +3231,11 @@ declare namespace ts { updateTypeReferenceNode(node: TypeReferenceNode, typeName: EntityName, typeArguments: NodeArray | undefined): TypeReferenceNode; createFunctionTypeNode(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): FunctionTypeNode; updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray | undefined, parameters: NodeArray, type: TypeNode): FunctionTypeNode; + createConstructorTypeNode(modifiers: readonly Modifier[] | undefined, typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): ConstructorTypeNode; + /** @deprecated */ createConstructorTypeNode(typeParameters: readonly TypeParameterDeclaration[] | undefined, parameters: readonly ParameterDeclaration[], type: TypeNode): ConstructorTypeNode; + 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; @@ -6854,9 +6858,9 @@ declare namespace ts { /** @deprecated Use `factory.updateEnumDeclaration` or the factory supplied by your transformation context instead. */ const updateEnumDeclaration: (node: EnumDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: Identifier, members: readonly EnumMember[]) => EnumDeclaration; /** @deprecated Use `factory.createModuleDeclaration` or the factory supplied by your transformation context instead. */ - const createModuleDeclaration: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: ModuleName, body: Identifier | ModuleBlock | NamespaceDeclaration | JSDocNamespaceDeclaration | undefined, flags?: NodeFlags | undefined) => ModuleDeclaration; + const createModuleDeclaration: (decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: ModuleName, body: ModuleBlock | NamespaceDeclaration | Identifier | JSDocNamespaceDeclaration | undefined, flags?: NodeFlags | undefined) => ModuleDeclaration; /** @deprecated Use `factory.updateModuleDeclaration` or the factory supplied by your transformation context instead. */ - const updateModuleDeclaration: (node: ModuleDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: ModuleName, body: Identifier | ModuleBlock | NamespaceDeclaration | JSDocNamespaceDeclaration | undefined) => ModuleDeclaration; + const updateModuleDeclaration: (node: ModuleDeclaration, decorators: readonly Decorator[] | undefined, modifiers: readonly Modifier[] | undefined, name: ModuleName, body: ModuleBlock | NamespaceDeclaration | Identifier | JSDocNamespaceDeclaration | undefined) => ModuleDeclaration; /** @deprecated Use `factory.createModuleBlock` or the factory supplied by your transformation context instead. */ const createModuleBlock: (statements: readonly Statement[]) => ModuleBlock; /** @deprecated Use `factory.updateModuleBlock` or the factory supplied by your transformation context instead. */ diff --git a/tests/baselines/reference/assignmentCompatability45.errors.txt b/tests/baselines/reference/assignmentCompatability45.errors.txt index 7a01b39841be6..af0170320bd1d 100644 --- a/tests/baselines/reference/assignmentCompatability45.errors.txt +++ b/tests/baselines/reference/assignmentCompatability45.errors.txt @@ -1,6 +1,6 @@ tests/cases/compiler/assignmentCompatability45.ts(7,7): error TS2322: Type 'typeof B' is not assignable to type 'typeof A'. Types of construct signatures are incompatible. - Type 'new (x: number) => B' is not assignable to type 'new () => A'. + Type 'new (x: number) => B' is not assignable to type 'abstract new () => A'. ==== tests/cases/compiler/assignmentCompatability45.ts (1 errors) ==== @@ -14,5 +14,5 @@ tests/cases/compiler/assignmentCompatability45.ts(7,7): error TS2322: Type 'type ~ !!! error TS2322: Type 'typeof B' is not assignable to type 'typeof A'. !!! error TS2322: Types of construct signatures are incompatible. -!!! error TS2322: Type 'new (x: number) => B' is not assignable to type 'new () => A'. +!!! error TS2322: Type 'new (x: number) => B' is not assignable to type 'abstract new () => A'. \ No newline at end of file diff --git a/tests/baselines/reference/declarationEmitLocalClassDeclarationMixin.js b/tests/baselines/reference/declarationEmitLocalClassDeclarationMixin.js index 73399ba507a72..eff59f1c5389a 100644 --- a/tests/baselines/reference/declarationEmitLocalClassDeclarationMixin.js +++ b/tests/baselines/reference/declarationEmitLocalClassDeclarationMixin.js @@ -104,12 +104,10 @@ export declare const Mixed: { bar: number; }; } & typeof Unmixed; -declare const FilteredThing_base: { - new (...args: any[]): { - match(path: string): boolean; - thing: number; - }; -} & typeof Unmixed; +declare const FilteredThing_base: (abstract new (...args: any[]) => { + match(path: string): boolean; + thing: number; +}) & typeof Unmixed; export declare class FilteredThing extends FilteredThing_base { match(path: string): boolean; } diff --git a/tests/baselines/reference/declarationEmitLocalClassDeclarationMixin.types b/tests/baselines/reference/declarationEmitLocalClassDeclarationMixin.types index b63fd97e1ec2f..6a8bd24273f07 100644 --- a/tests/baselines/reference/declarationEmitLocalClassDeclarationMixin.types +++ b/tests/baselines/reference/declarationEmitLocalClassDeclarationMixin.types @@ -33,7 +33,7 @@ export const Mixed = mixin(Unmixed); >Unmixed : typeof Unmixed function Filter>(ctor: C) { ->Filter : >(ctor: C) => { new (...args: any[]): FilterMixin; prototype: Filter.FilterMixin; } & C +>Filter : >(ctor: C) => ((abstract new (...args: any[]) => FilterMixin) & { prototype: Filter.FilterMixin; }) & C >ctor : C abstract class FilterMixin extends ctor { @@ -50,13 +50,13 @@ function Filter>(ctor: C) { >12 : 12 } return FilterMixin; ->FilterMixin : { new (...args: any[]): FilterMixin; prototype: Filter.FilterMixin; } & C +>FilterMixin : ((abstract new (...args: any[]) => FilterMixin) & { prototype: Filter.FilterMixin; }) & C } export class FilteredThing extends Filter(Unmixed) { >FilteredThing : FilteredThing >Filter(Unmixed) : Filter.FilterMixin & Unmixed ->Filter : >(ctor: C) => { new (...args: any[]): FilterMixin; prototype: Filter.FilterMixin; } & C +>Filter : >(ctor: C) => ((abstract new (...args: any[]) => FilterMixin) & { prototype: Filter.FilterMixin; }) & C >Unmixed : typeof Unmixed match(path: string) { diff --git a/tests/baselines/reference/inferTypes1.errors.txt b/tests/baselines/reference/inferTypes1.errors.txt index 3779d91bf2b01..d1ab94f7af991 100644 --- a/tests/baselines/reference/inferTypes1.errors.txt +++ b/tests/baselines/reference/inferTypes1.errors.txt @@ -1,27 +1,31 @@ -tests/cases/conformance/types/conditional/inferTypes1.ts(31,23): error TS2344: Type 'string' does not satisfy the constraint '(...args: any) => any'. -tests/cases/conformance/types/conditional/inferTypes1.ts(32,23): error TS2344: Type 'Function' does not satisfy the constraint '(...args: any) => any'. +tests/cases/conformance/types/conditional/inferTypes1.ts(36,23): error TS2344: Type 'string' does not satisfy the constraint '(...args: any) => any'. +tests/cases/conformance/types/conditional/inferTypes1.ts(37,23): error TS2344: Type 'Function' does not satisfy the constraint '(...args: any) => any'. Type 'Function' provides no match for the signature '(...args: any): any'. -tests/cases/conformance/types/conditional/inferTypes1.ts(38,25): error TS2344: Type 'string' does not satisfy the constraint 'new (...args: any) => any'. -tests/cases/conformance/types/conditional/inferTypes1.ts(39,25): error TS2344: Type 'Function' does not satisfy the constraint 'new (...args: any) => any'. +tests/cases/conformance/types/conditional/inferTypes1.ts(43,25): error TS2344: Type 'string' does not satisfy the constraint 'new (...args: any) => any'. +tests/cases/conformance/types/conditional/inferTypes1.ts(44,25): error TS2344: Type 'Function' does not satisfy the constraint 'new (...args: any) => any'. Type 'Function' provides no match for the signature 'new (...args: any): any'. -tests/cases/conformance/types/conditional/inferTypes1.ts(47,25): error TS2344: Type '(x: string, y: string) => number' does not satisfy the constraint '(x: any) => any'. -tests/cases/conformance/types/conditional/inferTypes1.ts(48,25): error TS2344: Type 'Function' does not satisfy the constraint '(x: any) => any'. +tests/cases/conformance/types/conditional/inferTypes1.ts(45,25): error TS2344: Type 'typeof Abstract' does not satisfy the constraint 'new (...args: any) => any'. + Cannot assign an abstract constructor type to a non-abstract constructor type. +tests/cases/conformance/types/conditional/inferTypes1.ts(47,42): error TS2344: Type 'abstract new (x: string, ...args: T) => T[]' does not satisfy the constraint 'new (...args: any) => any'. + Cannot assign an abstract constructor type to a non-abstract constructor type. +tests/cases/conformance/types/conditional/inferTypes1.ts(55,25): error TS2344: Type '(x: string, y: string) => number' does not satisfy the constraint '(x: any) => any'. +tests/cases/conformance/types/conditional/inferTypes1.ts(56,25): error TS2344: Type 'Function' does not satisfy the constraint '(x: any) => any'. Type 'Function' provides no match for the signature '(x: any): any'. -tests/cases/conformance/types/conditional/inferTypes1.ts(74,12): error TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type. -tests/cases/conformance/types/conditional/inferTypes1.ts(75,15): error TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type. -tests/cases/conformance/types/conditional/inferTypes1.ts(75,41): error TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type. -tests/cases/conformance/types/conditional/inferTypes1.ts(75,51): error TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type. -tests/cases/conformance/types/conditional/inferTypes1.ts(76,15): error TS2304: Cannot find name 'U'. -tests/cases/conformance/types/conditional/inferTypes1.ts(76,15): error TS4081: Exported type alias 'T62' has or is using private name 'U'. -tests/cases/conformance/types/conditional/inferTypes1.ts(76,43): error TS2304: Cannot find name 'U'. -tests/cases/conformance/types/conditional/inferTypes1.ts(76,43): error TS4081: Exported type alias 'T62' has or is using private name 'U'. -tests/cases/conformance/types/conditional/inferTypes1.ts(83,44): error TS2344: Type 'U' does not satisfy the constraint 'string'. +tests/cases/conformance/types/conditional/inferTypes1.ts(82,12): error TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type. +tests/cases/conformance/types/conditional/inferTypes1.ts(83,15): error TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type. +tests/cases/conformance/types/conditional/inferTypes1.ts(83,41): error TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type. +tests/cases/conformance/types/conditional/inferTypes1.ts(83,51): error TS1338: 'infer' declarations are only permitted in the 'extends' clause of a conditional type. +tests/cases/conformance/types/conditional/inferTypes1.ts(84,15): error TS2304: Cannot find name 'U'. +tests/cases/conformance/types/conditional/inferTypes1.ts(84,15): error TS4081: Exported type alias 'T62' has or is using private name 'U'. +tests/cases/conformance/types/conditional/inferTypes1.ts(84,43): error TS2304: Cannot find name 'U'. +tests/cases/conformance/types/conditional/inferTypes1.ts(84,43): error TS4081: Exported type alias 'T62' has or is using private name 'U'. +tests/cases/conformance/types/conditional/inferTypes1.ts(91,44): error TS2344: Type 'U' does not satisfy the constraint 'string'. Type 'number' is not assignable to type 'string'. -tests/cases/conformance/types/conditional/inferTypes1.ts(145,40): error TS2322: Type 'T' is not assignable to type 'string | number | symbol'. +tests/cases/conformance/types/conditional/inferTypes1.ts(153,40): error TS2322: Type 'T' is not assignable to type 'string | number | symbol'. Type 'T' is not assignable to type 'symbol'. -==== tests/cases/conformance/types/conditional/inferTypes1.ts (16 errors) ==== +==== tests/cases/conformance/types/conditional/inferTypes1.ts (18 errors) ==== type Unpacked = T extends (infer U)[] ? U : T extends (...args: any[]) => infer U ? U : @@ -45,6 +49,11 @@ tests/cases/conformance/types/conditional/inferTypes1.ts(145,40): error TS2322: y = 0; } + abstract class Abstract { + x = 0; + y = 0; + } + type T10 = ReturnType<() => string>; // string type T11 = ReturnType<(s: string) => void>; // void type T12 = ReturnType<(() => T)>; // {} @@ -71,6 +80,15 @@ tests/cases/conformance/types/conditional/inferTypes1.ts(145,40): error TS2322: ~~~~~~~~ !!! error TS2344: Type 'Function' does not satisfy the constraint 'new (...args: any) => any'. !!! error TS2344: Type 'Function' provides no match for the signature 'new (...args: any): any'. + type U15 = InstanceType; // Abstract + ~~~~~~~~~~~~~~~ +!!! error TS2344: Type 'typeof Abstract' does not satisfy the constraint 'new (...args: any) => any'. +!!! error TS2344: Cannot assign an abstract constructor type to a non-abstract constructor type. + type U16 = InstanceType T[]>; // T[] + type U17 = InstanceType T[]>; // T[] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2344: Type 'abstract new (x: string, ...args: T) => T[]' does not satisfy the constraint 'new (...args: any) => any'. +!!! error TS2344: Cannot assign an abstract constructor type to a non-abstract constructor type. type ArgumentType any> = T extends (a: infer A) => any ? A : any; diff --git a/tests/baselines/reference/inferTypes1.js b/tests/baselines/reference/inferTypes1.js index 01dc5a797f224..e3e2b88dd4edb 100644 --- a/tests/baselines/reference/inferTypes1.js +++ b/tests/baselines/reference/inferTypes1.js @@ -22,6 +22,11 @@ class C { y = 0; } +abstract class Abstract { + x = 0; + y = 0; +} + type T10 = ReturnType<() => string>; // string type T11 = ReturnType<(s: string) => void>; // void type T12 = ReturnType<(() => T)>; // {} @@ -38,6 +43,9 @@ type U11 = InstanceType; // any type U12 = InstanceType; // never type U13 = InstanceType; // Error type U14 = InstanceType; // Error +type U15 = InstanceType; // Abstract +type U16 = InstanceType T[]>; // T[] +type U17 = InstanceType T[]>; // T[] type ArgumentType any> = T extends (a: infer A) => any ? A : any; @@ -191,6 +199,13 @@ var C = /** @class */ (function () { } return C; }()); +var Abstract = /** @class */ (function () { + function Abstract() { + this.x = 0; + this.y = 0; + } + return Abstract; +}()); var z1 = ex.customClass; var z2 = ex.obj.nested.attr; // Repros from #26856 diff --git a/tests/baselines/reference/inferTypes1.symbols b/tests/baselines/reference/inferTypes1.symbols index 609a0093290a7..a7e2b0ac5d8f6 100644 --- a/tests/baselines/reference/inferTypes1.symbols +++ b/tests/baselines/reference/inferTypes1.symbols @@ -74,669 +74,702 @@ class C { >y : Symbol(C.y, Decl(inferTypes1.ts, 19, 10)) } +abstract class Abstract { +>Abstract : Symbol(Abstract, Decl(inferTypes1.ts, 21, 1)) + + x = 0; +>x : Symbol(Abstract.x, Decl(inferTypes1.ts, 23, 25)) + + y = 0; +>y : Symbol(Abstract.y, Decl(inferTypes1.ts, 24, 10)) +} + type T10 = ReturnType<() => string>; // string ->T10 : Symbol(T10, Decl(inferTypes1.ts, 21, 1)) +>T10 : Symbol(T10, Decl(inferTypes1.ts, 26, 1)) >ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) type T11 = ReturnType<(s: string) => void>; // void ->T11 : Symbol(T11, Decl(inferTypes1.ts, 23, 36)) +>T11 : Symbol(T11, Decl(inferTypes1.ts, 28, 36)) >ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) ->s : Symbol(s, Decl(inferTypes1.ts, 24, 23)) +>s : Symbol(s, Decl(inferTypes1.ts, 29, 23)) type T12 = ReturnType<(() => T)>; // {} ->T12 : Symbol(T12, Decl(inferTypes1.ts, 24, 43)) +>T12 : Symbol(T12, Decl(inferTypes1.ts, 29, 43)) >ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) ->T : Symbol(T, Decl(inferTypes1.ts, 25, 24)) ->T : Symbol(T, Decl(inferTypes1.ts, 25, 24)) +>T : Symbol(T, Decl(inferTypes1.ts, 30, 24)) +>T : Symbol(T, Decl(inferTypes1.ts, 30, 24)) type T13 = ReturnType<(() => T)>; // number[] ->T13 : Symbol(T13, Decl(inferTypes1.ts, 25, 36)) +>T13 : Symbol(T13, Decl(inferTypes1.ts, 30, 36)) >ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) ->T : Symbol(T, Decl(inferTypes1.ts, 26, 24)) ->U : Symbol(U, Decl(inferTypes1.ts, 26, 36)) ->U : Symbol(U, Decl(inferTypes1.ts, 26, 36)) ->T : Symbol(T, Decl(inferTypes1.ts, 26, 24)) +>T : Symbol(T, Decl(inferTypes1.ts, 31, 24)) +>U : Symbol(U, Decl(inferTypes1.ts, 31, 36)) +>U : Symbol(U, Decl(inferTypes1.ts, 31, 36)) +>T : Symbol(T, Decl(inferTypes1.ts, 31, 24)) type T14 = ReturnType; // { a: number, b: string } ->T14 : Symbol(T14, Decl(inferTypes1.ts, 26, 66)) +>T14 : Symbol(T14, Decl(inferTypes1.ts, 31, 66)) >ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) >f1 : Symbol(f1, Decl(inferTypes1.ts, 12, 27)) type T15 = ReturnType; // any ->T15 : Symbol(T15, Decl(inferTypes1.ts, 27, 33)) +>T15 : Symbol(T15, Decl(inferTypes1.ts, 32, 33)) >ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) type T16 = ReturnType; // never ->T16 : Symbol(T16, Decl(inferTypes1.ts, 28, 27)) +>T16 : Symbol(T16, Decl(inferTypes1.ts, 33, 27)) >ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) type T17 = ReturnType; // Error ->T17 : Symbol(T17, Decl(inferTypes1.ts, 29, 29)) +>T17 : Symbol(T17, Decl(inferTypes1.ts, 34, 29)) >ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) type T18 = ReturnType; // Error ->T18 : Symbol(T18, Decl(inferTypes1.ts, 30, 30)) +>T18 : Symbol(T18, Decl(inferTypes1.ts, 35, 30)) >ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) >Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) type T19 = ReturnType<(x: string, ...args: T) => T[]>; // T[] ->T19 : Symbol(T19, Decl(inferTypes1.ts, 31, 32)) ->T : Symbol(T, Decl(inferTypes1.ts, 32, 9)) +>T19 : Symbol(T19, Decl(inferTypes1.ts, 36, 32)) +>T : Symbol(T, Decl(inferTypes1.ts, 37, 9)) >ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) ->x : Symbol(x, Decl(inferTypes1.ts, 32, 40)) ->args : Symbol(args, Decl(inferTypes1.ts, 32, 50)) ->T : Symbol(T, Decl(inferTypes1.ts, 32, 9)) ->T : Symbol(T, Decl(inferTypes1.ts, 32, 9)) +>x : Symbol(x, Decl(inferTypes1.ts, 37, 40)) +>args : Symbol(args, Decl(inferTypes1.ts, 37, 50)) +>T : Symbol(T, Decl(inferTypes1.ts, 37, 9)) +>T : Symbol(T, Decl(inferTypes1.ts, 37, 9)) type U10 = InstanceType; // C ->U10 : Symbol(U10, Decl(inferTypes1.ts, 32, 71)) +>U10 : Symbol(U10, Decl(inferTypes1.ts, 37, 71)) >InstanceType : Symbol(InstanceType, Decl(lib.es5.d.ts, --, --)) >C : Symbol(C, Decl(inferTypes1.ts, 16, 1)) type U11 = InstanceType; // any ->U11 : Symbol(U11, Decl(inferTypes1.ts, 34, 34)) +>U11 : Symbol(U11, Decl(inferTypes1.ts, 39, 34)) >InstanceType : Symbol(InstanceType, Decl(lib.es5.d.ts, --, --)) type U12 = InstanceType; // never ->U12 : Symbol(U12, Decl(inferTypes1.ts, 35, 29)) +>U12 : Symbol(U12, Decl(inferTypes1.ts, 40, 29)) >InstanceType : Symbol(InstanceType, Decl(lib.es5.d.ts, --, --)) type U13 = InstanceType; // Error ->U13 : Symbol(U13, Decl(inferTypes1.ts, 36, 31)) +>U13 : Symbol(U13, Decl(inferTypes1.ts, 41, 31)) >InstanceType : Symbol(InstanceType, Decl(lib.es5.d.ts, --, --)) type U14 = InstanceType; // Error ->U14 : Symbol(U14, Decl(inferTypes1.ts, 37, 32)) +>U14 : Symbol(U14, Decl(inferTypes1.ts, 42, 32)) >InstanceType : Symbol(InstanceType, Decl(lib.es5.d.ts, --, --)) >Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) +type U15 = InstanceType; // Abstract +>U15 : Symbol(U15, Decl(inferTypes1.ts, 43, 34)) +>InstanceType : Symbol(InstanceType, Decl(lib.es5.d.ts, --, --)) +>Abstract : Symbol(Abstract, Decl(inferTypes1.ts, 21, 1)) + +type U16 = InstanceType T[]>; // T[] +>U16 : Symbol(U16, Decl(inferTypes1.ts, 44, 41)) +>T : Symbol(T, Decl(inferTypes1.ts, 45, 9)) +>InstanceType : Symbol(InstanceType, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(inferTypes1.ts, 45, 46)) +>args : Symbol(args, Decl(inferTypes1.ts, 45, 56)) +>T : Symbol(T, Decl(inferTypes1.ts, 45, 9)) +>T : Symbol(T, Decl(inferTypes1.ts, 45, 9)) + +type U17 = InstanceType T[]>; // T[] +>U17 : Symbol(U17, Decl(inferTypes1.ts, 45, 77)) +>T : Symbol(T, Decl(inferTypes1.ts, 46, 9)) +>InstanceType : Symbol(InstanceType, Decl(lib.es5.d.ts, --, --)) +>x : Symbol(x, Decl(inferTypes1.ts, 46, 55)) +>args : Symbol(args, Decl(inferTypes1.ts, 46, 65)) +>T : Symbol(T, Decl(inferTypes1.ts, 46, 9)) +>T : Symbol(T, Decl(inferTypes1.ts, 46, 9)) + type ArgumentType any> = T extends (a: infer A) => any ? A : any; ->ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 38, 34)) ->T : Symbol(T, Decl(inferTypes1.ts, 40, 18)) ->x : Symbol(x, Decl(inferTypes1.ts, 40, 29)) ->T : Symbol(T, Decl(inferTypes1.ts, 40, 18)) ->a : Symbol(a, Decl(inferTypes1.ts, 40, 58)) ->A : Symbol(A, Decl(inferTypes1.ts, 40, 66)) ->A : Symbol(A, Decl(inferTypes1.ts, 40, 66)) +>ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 46, 86)) +>T : Symbol(T, Decl(inferTypes1.ts, 48, 18)) +>x : Symbol(x, Decl(inferTypes1.ts, 48, 29)) +>T : Symbol(T, Decl(inferTypes1.ts, 48, 18)) +>a : Symbol(a, Decl(inferTypes1.ts, 48, 58)) +>A : Symbol(A, Decl(inferTypes1.ts, 48, 66)) +>A : Symbol(A, Decl(inferTypes1.ts, 48, 66)) type T20 = ArgumentType<() => void>; // {} ->T20 : Symbol(T20, Decl(inferTypes1.ts, 40, 87)) ->ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 38, 34)) +>T20 : Symbol(T20, Decl(inferTypes1.ts, 48, 87)) +>ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 46, 86)) type T21 = ArgumentType<(x: string) => number>; // string ->T21 : Symbol(T21, Decl(inferTypes1.ts, 42, 36)) ->ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 38, 34)) ->x : Symbol(x, Decl(inferTypes1.ts, 43, 25)) +>T21 : Symbol(T21, Decl(inferTypes1.ts, 50, 36)) +>ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 46, 86)) +>x : Symbol(x, Decl(inferTypes1.ts, 51, 25)) type T22 = ArgumentType<(x?: string) => number>; // string | undefined ->T22 : Symbol(T22, Decl(inferTypes1.ts, 43, 47)) ->ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 38, 34)) ->x : Symbol(x, Decl(inferTypes1.ts, 44, 25)) +>T22 : Symbol(T22, Decl(inferTypes1.ts, 51, 47)) +>ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 46, 86)) +>x : Symbol(x, Decl(inferTypes1.ts, 52, 25)) type T23 = ArgumentType<(...args: string[]) => number>; // string ->T23 : Symbol(T23, Decl(inferTypes1.ts, 44, 48)) ->ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 38, 34)) ->args : Symbol(args, Decl(inferTypes1.ts, 45, 25)) +>T23 : Symbol(T23, Decl(inferTypes1.ts, 52, 48)) +>ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 46, 86)) +>args : Symbol(args, Decl(inferTypes1.ts, 53, 25)) type T24 = ArgumentType<(x: string, y: string) => number>; // Error ->T24 : Symbol(T24, Decl(inferTypes1.ts, 45, 55)) ->ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 38, 34)) ->x : Symbol(x, Decl(inferTypes1.ts, 46, 25)) ->y : Symbol(y, Decl(inferTypes1.ts, 46, 35)) +>T24 : Symbol(T24, Decl(inferTypes1.ts, 53, 55)) +>ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 46, 86)) +>x : Symbol(x, Decl(inferTypes1.ts, 54, 25)) +>y : Symbol(y, Decl(inferTypes1.ts, 54, 35)) type T25 = ArgumentType; // Error ->T25 : Symbol(T25, Decl(inferTypes1.ts, 46, 58)) ->ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 38, 34)) +>T25 : Symbol(T25, Decl(inferTypes1.ts, 54, 58)) +>ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 46, 86)) >Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) type T26 = ArgumentType; // any ->T26 : Symbol(T26, Decl(inferTypes1.ts, 47, 34)) ->ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 38, 34)) +>T26 : Symbol(T26, Decl(inferTypes1.ts, 55, 34)) +>ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 46, 86)) type T27 = ArgumentType; // never ->T27 : Symbol(T27, Decl(inferTypes1.ts, 48, 29)) ->ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 38, 34)) +>T27 : Symbol(T27, Decl(inferTypes1.ts, 56, 29)) +>ArgumentType : Symbol(ArgumentType, Decl(inferTypes1.ts, 46, 86)) type X1 = T extends { x: infer X, y: infer Y } ? [X, Y] : any; ->X1 : Symbol(X1, Decl(inferTypes1.ts, 49, 31)) ->T : Symbol(T, Decl(inferTypes1.ts, 51, 8)) ->x : Symbol(x, Decl(inferTypes1.ts, 51, 19)) ->y : Symbol(y, Decl(inferTypes1.ts, 51, 27)) ->T : Symbol(T, Decl(inferTypes1.ts, 51, 8)) ->x : Symbol(x, Decl(inferTypes1.ts, 51, 51)) ->X : Symbol(X, Decl(inferTypes1.ts, 51, 60)) ->y : Symbol(y, Decl(inferTypes1.ts, 51, 63)) ->Y : Symbol(Y, Decl(inferTypes1.ts, 51, 72)) ->X : Symbol(X, Decl(inferTypes1.ts, 51, 60)) ->Y : Symbol(Y, Decl(inferTypes1.ts, 51, 72)) +>X1 : Symbol(X1, Decl(inferTypes1.ts, 57, 31)) +>T : Symbol(T, Decl(inferTypes1.ts, 59, 8)) +>x : Symbol(x, Decl(inferTypes1.ts, 59, 19)) +>y : Symbol(y, Decl(inferTypes1.ts, 59, 27)) +>T : Symbol(T, Decl(inferTypes1.ts, 59, 8)) +>x : Symbol(x, Decl(inferTypes1.ts, 59, 51)) +>X : Symbol(X, Decl(inferTypes1.ts, 59, 60)) +>y : Symbol(y, Decl(inferTypes1.ts, 59, 63)) +>Y : Symbol(Y, Decl(inferTypes1.ts, 59, 72)) +>X : Symbol(X, Decl(inferTypes1.ts, 59, 60)) +>Y : Symbol(Y, Decl(inferTypes1.ts, 59, 72)) type T30 = X1<{ x: any, y: any }>; // [any, any] ->T30 : Symbol(T30, Decl(inferTypes1.ts, 51, 92)) ->X1 : Symbol(X1, Decl(inferTypes1.ts, 49, 31)) ->x : Symbol(x, Decl(inferTypes1.ts, 53, 15)) ->y : Symbol(y, Decl(inferTypes1.ts, 53, 23)) +>T30 : Symbol(T30, Decl(inferTypes1.ts, 59, 92)) +>X1 : Symbol(X1, Decl(inferTypes1.ts, 57, 31)) +>x : Symbol(x, Decl(inferTypes1.ts, 61, 15)) +>y : Symbol(y, Decl(inferTypes1.ts, 61, 23)) type T31 = X1<{ x: number, y: string }>; // [number, string] ->T31 : Symbol(T31, Decl(inferTypes1.ts, 53, 34)) ->X1 : Symbol(X1, Decl(inferTypes1.ts, 49, 31)) ->x : Symbol(x, Decl(inferTypes1.ts, 54, 15)) ->y : Symbol(y, Decl(inferTypes1.ts, 54, 26)) +>T31 : Symbol(T31, Decl(inferTypes1.ts, 61, 34)) +>X1 : Symbol(X1, Decl(inferTypes1.ts, 57, 31)) +>x : Symbol(x, Decl(inferTypes1.ts, 62, 15)) +>y : Symbol(y, Decl(inferTypes1.ts, 62, 26)) type T32 = X1<{ x: number, y: string, z: boolean }>; // [number, string] ->T32 : Symbol(T32, Decl(inferTypes1.ts, 54, 40)) ->X1 : Symbol(X1, Decl(inferTypes1.ts, 49, 31)) ->x : Symbol(x, Decl(inferTypes1.ts, 55, 15)) ->y : Symbol(y, Decl(inferTypes1.ts, 55, 26)) ->z : Symbol(z, Decl(inferTypes1.ts, 55, 37)) +>T32 : Symbol(T32, Decl(inferTypes1.ts, 62, 40)) +>X1 : Symbol(X1, Decl(inferTypes1.ts, 57, 31)) +>x : Symbol(x, Decl(inferTypes1.ts, 63, 15)) +>y : Symbol(y, Decl(inferTypes1.ts, 63, 26)) +>z : Symbol(z, Decl(inferTypes1.ts, 63, 37)) type X2 = T extends { a: infer U, b: infer U } ? U : never; ->X2 : Symbol(X2, Decl(inferTypes1.ts, 55, 52)) ->T : Symbol(T, Decl(inferTypes1.ts, 57, 8)) ->T : Symbol(T, Decl(inferTypes1.ts, 57, 8)) ->a : Symbol(a, Decl(inferTypes1.ts, 57, 24)) ->U : Symbol(U, Decl(inferTypes1.ts, 57, 33), Decl(inferTypes1.ts, 57, 45)) ->b : Symbol(b, Decl(inferTypes1.ts, 57, 36)) ->U : Symbol(U, Decl(inferTypes1.ts, 57, 33), Decl(inferTypes1.ts, 57, 45)) ->U : Symbol(U, Decl(inferTypes1.ts, 57, 33), Decl(inferTypes1.ts, 57, 45)) +>X2 : Symbol(X2, Decl(inferTypes1.ts, 63, 52)) +>T : Symbol(T, Decl(inferTypes1.ts, 65, 8)) +>T : Symbol(T, Decl(inferTypes1.ts, 65, 8)) +>a : Symbol(a, Decl(inferTypes1.ts, 65, 24)) +>U : Symbol(U, Decl(inferTypes1.ts, 65, 33), Decl(inferTypes1.ts, 65, 45)) +>b : Symbol(b, Decl(inferTypes1.ts, 65, 36)) +>U : Symbol(U, Decl(inferTypes1.ts, 65, 33), Decl(inferTypes1.ts, 65, 45)) +>U : Symbol(U, Decl(inferTypes1.ts, 65, 33), Decl(inferTypes1.ts, 65, 45)) type T40 = X2<{}>; // never ->T40 : Symbol(T40, Decl(inferTypes1.ts, 57, 62)) ->X2 : Symbol(X2, Decl(inferTypes1.ts, 55, 52)) +>T40 : Symbol(T40, Decl(inferTypes1.ts, 65, 62)) +>X2 : Symbol(X2, Decl(inferTypes1.ts, 63, 52)) type T41 = X2<{ a: string }>; // never ->T41 : Symbol(T41, Decl(inferTypes1.ts, 59, 18)) ->X2 : Symbol(X2, Decl(inferTypes1.ts, 55, 52)) ->a : Symbol(a, Decl(inferTypes1.ts, 60, 15)) +>T41 : Symbol(T41, Decl(inferTypes1.ts, 67, 18)) +>X2 : Symbol(X2, Decl(inferTypes1.ts, 63, 52)) +>a : Symbol(a, Decl(inferTypes1.ts, 68, 15)) type T42 = X2<{ a: string, b: string }>; // string ->T42 : Symbol(T42, Decl(inferTypes1.ts, 60, 29)) ->X2 : Symbol(X2, Decl(inferTypes1.ts, 55, 52)) ->a : Symbol(a, Decl(inferTypes1.ts, 61, 15)) ->b : Symbol(b, Decl(inferTypes1.ts, 61, 26)) +>T42 : Symbol(T42, Decl(inferTypes1.ts, 68, 29)) +>X2 : Symbol(X2, Decl(inferTypes1.ts, 63, 52)) +>a : Symbol(a, Decl(inferTypes1.ts, 69, 15)) +>b : Symbol(b, Decl(inferTypes1.ts, 69, 26)) type T43 = X2<{ a: number, b: string }>; // string | number ->T43 : Symbol(T43, Decl(inferTypes1.ts, 61, 40)) ->X2 : Symbol(X2, Decl(inferTypes1.ts, 55, 52)) ->a : Symbol(a, Decl(inferTypes1.ts, 62, 15)) ->b : Symbol(b, Decl(inferTypes1.ts, 62, 26)) +>T43 : Symbol(T43, Decl(inferTypes1.ts, 69, 40)) +>X2 : Symbol(X2, Decl(inferTypes1.ts, 63, 52)) +>a : Symbol(a, Decl(inferTypes1.ts, 70, 15)) +>b : Symbol(b, Decl(inferTypes1.ts, 70, 26)) type T44 = X2<{ a: number, b: string, c: boolean }>; // string | number ->T44 : Symbol(T44, Decl(inferTypes1.ts, 62, 40)) ->X2 : Symbol(X2, Decl(inferTypes1.ts, 55, 52)) ->a : Symbol(a, Decl(inferTypes1.ts, 63, 15)) ->b : Symbol(b, Decl(inferTypes1.ts, 63, 26)) ->c : Symbol(c, Decl(inferTypes1.ts, 63, 37)) +>T44 : Symbol(T44, Decl(inferTypes1.ts, 70, 40)) +>X2 : Symbol(X2, Decl(inferTypes1.ts, 63, 52)) +>a : Symbol(a, Decl(inferTypes1.ts, 71, 15)) +>b : Symbol(b, Decl(inferTypes1.ts, 71, 26)) +>c : Symbol(c, Decl(inferTypes1.ts, 71, 37)) type X3 = T extends { a: (x: infer U) => void, b: (x: infer U) => void } ? U : never; ->X3 : Symbol(X3, Decl(inferTypes1.ts, 63, 52)) ->T : Symbol(T, Decl(inferTypes1.ts, 65, 8)) ->T : Symbol(T, Decl(inferTypes1.ts, 65, 8)) ->a : Symbol(a, Decl(inferTypes1.ts, 65, 24)) ->x : Symbol(x, Decl(inferTypes1.ts, 65, 29)) ->U : Symbol(U, Decl(inferTypes1.ts, 65, 37), Decl(inferTypes1.ts, 65, 62)) ->b : Symbol(b, Decl(inferTypes1.ts, 65, 49)) ->x : Symbol(x, Decl(inferTypes1.ts, 65, 54)) ->U : Symbol(U, Decl(inferTypes1.ts, 65, 37), Decl(inferTypes1.ts, 65, 62)) ->U : Symbol(U, Decl(inferTypes1.ts, 65, 37), Decl(inferTypes1.ts, 65, 62)) +>X3 : Symbol(X3, Decl(inferTypes1.ts, 71, 52)) +>T : Symbol(T, Decl(inferTypes1.ts, 73, 8)) +>T : Symbol(T, Decl(inferTypes1.ts, 73, 8)) +>a : Symbol(a, Decl(inferTypes1.ts, 73, 24)) +>x : Symbol(x, Decl(inferTypes1.ts, 73, 29)) +>U : Symbol(U, Decl(inferTypes1.ts, 73, 37), Decl(inferTypes1.ts, 73, 62)) +>b : Symbol(b, Decl(inferTypes1.ts, 73, 49)) +>x : Symbol(x, Decl(inferTypes1.ts, 73, 54)) +>U : Symbol(U, Decl(inferTypes1.ts, 73, 37), Decl(inferTypes1.ts, 73, 62)) +>U : Symbol(U, Decl(inferTypes1.ts, 73, 37), Decl(inferTypes1.ts, 73, 62)) type T50 = X3<{}>; // never ->T50 : Symbol(T50, Decl(inferTypes1.ts, 65, 88)) ->X3 : Symbol(X3, Decl(inferTypes1.ts, 63, 52)) +>T50 : Symbol(T50, Decl(inferTypes1.ts, 73, 88)) +>X3 : Symbol(X3, Decl(inferTypes1.ts, 71, 52)) type T51 = X3<{ a: (x: string) => void }>; // never ->T51 : Symbol(T51, Decl(inferTypes1.ts, 67, 18)) ->X3 : Symbol(X3, Decl(inferTypes1.ts, 63, 52)) ->a : Symbol(a, Decl(inferTypes1.ts, 68, 15)) ->x : Symbol(x, Decl(inferTypes1.ts, 68, 20)) +>T51 : Symbol(T51, Decl(inferTypes1.ts, 75, 18)) +>X3 : Symbol(X3, Decl(inferTypes1.ts, 71, 52)) +>a : Symbol(a, Decl(inferTypes1.ts, 76, 15)) +>x : Symbol(x, Decl(inferTypes1.ts, 76, 20)) type T52 = X3<{ a: (x: string) => void, b: (x: string) => void }>; // string ->T52 : Symbol(T52, Decl(inferTypes1.ts, 68, 42)) ->X3 : Symbol(X3, Decl(inferTypes1.ts, 63, 52)) ->a : Symbol(a, Decl(inferTypes1.ts, 69, 15)) ->x : Symbol(x, Decl(inferTypes1.ts, 69, 20)) ->b : Symbol(b, Decl(inferTypes1.ts, 69, 39)) ->x : Symbol(x, Decl(inferTypes1.ts, 69, 44)) +>T52 : Symbol(T52, Decl(inferTypes1.ts, 76, 42)) +>X3 : Symbol(X3, Decl(inferTypes1.ts, 71, 52)) +>a : Symbol(a, Decl(inferTypes1.ts, 77, 15)) +>x : Symbol(x, Decl(inferTypes1.ts, 77, 20)) +>b : Symbol(b, Decl(inferTypes1.ts, 77, 39)) +>x : Symbol(x, Decl(inferTypes1.ts, 77, 44)) type T53 = X3<{ a: (x: number) => void, b: (x: string) => void }>; // never ->T53 : Symbol(T53, Decl(inferTypes1.ts, 69, 66)) ->X3 : Symbol(X3, Decl(inferTypes1.ts, 63, 52)) ->a : Symbol(a, Decl(inferTypes1.ts, 70, 15)) ->x : Symbol(x, Decl(inferTypes1.ts, 70, 20)) ->b : Symbol(b, Decl(inferTypes1.ts, 70, 39)) ->x : Symbol(x, Decl(inferTypes1.ts, 70, 44)) +>T53 : Symbol(T53, Decl(inferTypes1.ts, 77, 66)) +>X3 : Symbol(X3, Decl(inferTypes1.ts, 71, 52)) +>a : Symbol(a, Decl(inferTypes1.ts, 78, 15)) +>x : Symbol(x, Decl(inferTypes1.ts, 78, 20)) +>b : Symbol(b, Decl(inferTypes1.ts, 78, 39)) +>x : Symbol(x, Decl(inferTypes1.ts, 78, 44)) type T54 = X3<{ a: (x: number) => void, b: () => void }>; // number ->T54 : Symbol(T54, Decl(inferTypes1.ts, 70, 66)) ->X3 : Symbol(X3, Decl(inferTypes1.ts, 63, 52)) ->a : Symbol(a, Decl(inferTypes1.ts, 71, 15)) ->x : Symbol(x, Decl(inferTypes1.ts, 71, 20)) ->b : Symbol(b, Decl(inferTypes1.ts, 71, 39)) +>T54 : Symbol(T54, Decl(inferTypes1.ts, 78, 66)) +>X3 : Symbol(X3, Decl(inferTypes1.ts, 71, 52)) +>a : Symbol(a, Decl(inferTypes1.ts, 79, 15)) +>x : Symbol(x, Decl(inferTypes1.ts, 79, 20)) +>b : Symbol(b, Decl(inferTypes1.ts, 79, 39)) type T60 = infer U; // Error ->T60 : Symbol(T60, Decl(inferTypes1.ts, 71, 57)) ->U : Symbol(U, Decl(inferTypes1.ts, 73, 16)) +>T60 : Symbol(T60, Decl(inferTypes1.ts, 79, 57)) +>U : Symbol(U, Decl(inferTypes1.ts, 81, 16)) type T61 = infer A extends infer B ? infer C : infer D; // Error ->T61 : Symbol(T61, Decl(inferTypes1.ts, 73, 19)) ->T : Symbol(T, Decl(inferTypes1.ts, 74, 9)) ->A : Symbol(A, Decl(inferTypes1.ts, 74, 19)) ->B : Symbol(B, Decl(inferTypes1.ts, 74, 35)) ->C : Symbol(C, Decl(inferTypes1.ts, 74, 45)) ->D : Symbol(D, Decl(inferTypes1.ts, 74, 55)) +>T61 : Symbol(T61, Decl(inferTypes1.ts, 81, 19)) +>T : Symbol(T, Decl(inferTypes1.ts, 82, 9)) +>A : Symbol(A, Decl(inferTypes1.ts, 82, 19)) +>B : Symbol(B, Decl(inferTypes1.ts, 82, 35)) +>C : Symbol(C, Decl(inferTypes1.ts, 82, 45)) +>D : Symbol(D, Decl(inferTypes1.ts, 82, 55)) type T62 = U extends (infer U)[] ? U : U; // Error ->T62 : Symbol(T62, Decl(inferTypes1.ts, 74, 58)) ->T : Symbol(T, Decl(inferTypes1.ts, 75, 9)) ->U : Symbol(U, Decl(inferTypes1.ts, 75, 30)) ->U : Symbol(U, Decl(inferTypes1.ts, 75, 30)) +>T62 : Symbol(T62, Decl(inferTypes1.ts, 82, 58)) +>T : Symbol(T, Decl(inferTypes1.ts, 83, 9)) +>U : Symbol(U, Decl(inferTypes1.ts, 83, 30)) +>U : Symbol(U, Decl(inferTypes1.ts, 83, 30)) type T63 = T extends (infer A extends infer B ? infer C : infer D) ? string : number; ->T63 : Symbol(T63, Decl(inferTypes1.ts, 75, 44)) ->T : Symbol(T, Decl(inferTypes1.ts, 76, 9)) ->T : Symbol(T, Decl(inferTypes1.ts, 76, 9)) ->A : Symbol(A, Decl(inferTypes1.ts, 76, 30)) ->B : Symbol(B, Decl(inferTypes1.ts, 76, 46)) ->C : Symbol(C, Decl(inferTypes1.ts, 76, 56)) ->D : Symbol(D, Decl(inferTypes1.ts, 76, 66)) +>T63 : Symbol(T63, Decl(inferTypes1.ts, 83, 44)) +>T : Symbol(T, Decl(inferTypes1.ts, 84, 9)) +>T : Symbol(T, Decl(inferTypes1.ts, 84, 9)) +>A : Symbol(A, Decl(inferTypes1.ts, 84, 30)) +>B : Symbol(B, Decl(inferTypes1.ts, 84, 46)) +>C : Symbol(C, Decl(inferTypes1.ts, 84, 56)) +>D : Symbol(D, Decl(inferTypes1.ts, 84, 66)) type T70 = { x: T }; ->T70 : Symbol(T70, Decl(inferTypes1.ts, 76, 88)) ->T : Symbol(T, Decl(inferTypes1.ts, 78, 9)) ->x : Symbol(x, Decl(inferTypes1.ts, 78, 30)) ->T : Symbol(T, Decl(inferTypes1.ts, 78, 9)) +>T70 : Symbol(T70, Decl(inferTypes1.ts, 84, 88)) +>T : Symbol(T, Decl(inferTypes1.ts, 86, 9)) +>x : Symbol(x, Decl(inferTypes1.ts, 86, 30)) +>T : Symbol(T, Decl(inferTypes1.ts, 86, 9)) type T71 = T extends T70 ? T70 : never; ->T71 : Symbol(T71, Decl(inferTypes1.ts, 78, 38)) ->T : Symbol(T, Decl(inferTypes1.ts, 79, 9)) ->T : Symbol(T, Decl(inferTypes1.ts, 79, 9)) ->T70 : Symbol(T70, Decl(inferTypes1.ts, 76, 88)) ->U : Symbol(U, Decl(inferTypes1.ts, 79, 33)) ->T70 : Symbol(T70, Decl(inferTypes1.ts, 76, 88)) ->U : Symbol(U, Decl(inferTypes1.ts, 79, 33)) +>T71 : Symbol(T71, Decl(inferTypes1.ts, 86, 38)) +>T : Symbol(T, Decl(inferTypes1.ts, 87, 9)) +>T : Symbol(T, Decl(inferTypes1.ts, 87, 9)) +>T70 : Symbol(T70, Decl(inferTypes1.ts, 84, 88)) +>U : Symbol(U, Decl(inferTypes1.ts, 87, 33)) +>T70 : Symbol(T70, Decl(inferTypes1.ts, 84, 88)) +>U : Symbol(U, Decl(inferTypes1.ts, 87, 33)) type T72 = { y: T }; ->T72 : Symbol(T72, Decl(inferTypes1.ts, 79, 54)) ->T : Symbol(T, Decl(inferTypes1.ts, 81, 9)) ->y : Symbol(y, Decl(inferTypes1.ts, 81, 30)) ->T : Symbol(T, Decl(inferTypes1.ts, 81, 9)) +>T72 : Symbol(T72, Decl(inferTypes1.ts, 87, 54)) +>T : Symbol(T, Decl(inferTypes1.ts, 89, 9)) +>y : Symbol(y, Decl(inferTypes1.ts, 89, 30)) +>T : Symbol(T, Decl(inferTypes1.ts, 89, 9)) type T73 = T extends T72 ? T70 : never; // Error ->T73 : Symbol(T73, Decl(inferTypes1.ts, 81, 38)) ->T : Symbol(T, Decl(inferTypes1.ts, 82, 9)) ->T : Symbol(T, Decl(inferTypes1.ts, 82, 9)) ->T72 : Symbol(T72, Decl(inferTypes1.ts, 79, 54)) ->U : Symbol(U, Decl(inferTypes1.ts, 82, 33)) ->T70 : Symbol(T70, Decl(inferTypes1.ts, 76, 88)) ->U : Symbol(U, Decl(inferTypes1.ts, 82, 33)) +>T73 : Symbol(T73, Decl(inferTypes1.ts, 89, 38)) +>T : Symbol(T, Decl(inferTypes1.ts, 90, 9)) +>T : Symbol(T, Decl(inferTypes1.ts, 90, 9)) +>T72 : Symbol(T72, Decl(inferTypes1.ts, 87, 54)) +>U : Symbol(U, Decl(inferTypes1.ts, 90, 33)) +>T70 : Symbol(T70, Decl(inferTypes1.ts, 84, 88)) +>U : Symbol(U, Decl(inferTypes1.ts, 90, 33)) type T74 = { x: T, y: U }; ->T74 : Symbol(T74, Decl(inferTypes1.ts, 82, 54)) ->T : Symbol(T, Decl(inferTypes1.ts, 84, 9)) ->U : Symbol(U, Decl(inferTypes1.ts, 84, 26)) ->x : Symbol(x, Decl(inferTypes1.ts, 84, 48)) ->T : Symbol(T, Decl(inferTypes1.ts, 84, 9)) ->y : Symbol(y, Decl(inferTypes1.ts, 84, 54)) ->U : Symbol(U, Decl(inferTypes1.ts, 84, 26)) +>T74 : Symbol(T74, Decl(inferTypes1.ts, 90, 54)) +>T : Symbol(T, Decl(inferTypes1.ts, 92, 9)) +>U : Symbol(U, Decl(inferTypes1.ts, 92, 26)) +>x : Symbol(x, Decl(inferTypes1.ts, 92, 48)) +>T : Symbol(T, Decl(inferTypes1.ts, 92, 9)) +>y : Symbol(y, Decl(inferTypes1.ts, 92, 54)) +>U : Symbol(U, Decl(inferTypes1.ts, 92, 26)) type T75 = T extends T74 ? T70 | T72 | T74 : never; ->T75 : Symbol(T75, Decl(inferTypes1.ts, 84, 62)) ->T : Symbol(T, Decl(inferTypes1.ts, 85, 9)) ->T : Symbol(T, Decl(inferTypes1.ts, 85, 9)) ->T74 : Symbol(T74, Decl(inferTypes1.ts, 82, 54)) ->U : Symbol(U, Decl(inferTypes1.ts, 85, 33), Decl(inferTypes1.ts, 85, 42)) ->U : Symbol(U, Decl(inferTypes1.ts, 85, 33), Decl(inferTypes1.ts, 85, 42)) ->T70 : Symbol(T70, Decl(inferTypes1.ts, 76, 88)) ->U : Symbol(U, Decl(inferTypes1.ts, 85, 33), Decl(inferTypes1.ts, 85, 42)) ->T72 : Symbol(T72, Decl(inferTypes1.ts, 79, 54)) ->U : Symbol(U, Decl(inferTypes1.ts, 85, 33), Decl(inferTypes1.ts, 85, 42)) ->T74 : Symbol(T74, Decl(inferTypes1.ts, 82, 54)) ->U : Symbol(U, Decl(inferTypes1.ts, 85, 33), Decl(inferTypes1.ts, 85, 42)) ->U : Symbol(U, Decl(inferTypes1.ts, 85, 33), Decl(inferTypes1.ts, 85, 42)) +>T75 : Symbol(T75, Decl(inferTypes1.ts, 92, 62)) +>T : Symbol(T, Decl(inferTypes1.ts, 93, 9)) +>T : Symbol(T, Decl(inferTypes1.ts, 93, 9)) +>T74 : Symbol(T74, Decl(inferTypes1.ts, 90, 54)) +>U : Symbol(U, Decl(inferTypes1.ts, 93, 33), Decl(inferTypes1.ts, 93, 42)) +>U : Symbol(U, Decl(inferTypes1.ts, 93, 33), Decl(inferTypes1.ts, 93, 42)) +>T70 : Symbol(T70, Decl(inferTypes1.ts, 84, 88)) +>U : Symbol(U, Decl(inferTypes1.ts, 93, 33), Decl(inferTypes1.ts, 93, 42)) +>T72 : Symbol(T72, Decl(inferTypes1.ts, 87, 54)) +>U : Symbol(U, Decl(inferTypes1.ts, 93, 33), Decl(inferTypes1.ts, 93, 42)) +>T74 : Symbol(T74, Decl(inferTypes1.ts, 90, 54)) +>U : Symbol(U, Decl(inferTypes1.ts, 93, 33), Decl(inferTypes1.ts, 93, 42)) +>U : Symbol(U, Decl(inferTypes1.ts, 93, 33), Decl(inferTypes1.ts, 93, 42)) type T76 = { x: T }; ->T76 : Symbol(T76, Decl(inferTypes1.ts, 85, 84)) ->T : Symbol(T, Decl(inferTypes1.ts, 87, 9)) ->T : Symbol(T, Decl(inferTypes1.ts, 87, 9)) ->U : Symbol(U, Decl(inferTypes1.ts, 87, 23)) ->T : Symbol(T, Decl(inferTypes1.ts, 87, 9)) ->x : Symbol(x, Decl(inferTypes1.ts, 87, 40)) ->T : Symbol(T, Decl(inferTypes1.ts, 87, 9)) +>T76 : Symbol(T76, Decl(inferTypes1.ts, 93, 84)) +>T : Symbol(T, Decl(inferTypes1.ts, 95, 9)) +>T : Symbol(T, Decl(inferTypes1.ts, 95, 9)) +>U : Symbol(U, Decl(inferTypes1.ts, 95, 23)) +>T : Symbol(T, Decl(inferTypes1.ts, 95, 9)) +>x : Symbol(x, Decl(inferTypes1.ts, 95, 40)) +>T : Symbol(T, Decl(inferTypes1.ts, 95, 9)) type T77 = T extends T76 ? T76 : never; ->T77 : Symbol(T77, Decl(inferTypes1.ts, 87, 48)) ->T : Symbol(T, Decl(inferTypes1.ts, 88, 9)) ->T : Symbol(T, Decl(inferTypes1.ts, 88, 9)) ->T76 : Symbol(T76, Decl(inferTypes1.ts, 85, 84)) ->X : Symbol(X, Decl(inferTypes1.ts, 88, 33)) ->Y : Symbol(Y, Decl(inferTypes1.ts, 88, 42)) ->T76 : Symbol(T76, Decl(inferTypes1.ts, 85, 84)) ->X : Symbol(X, Decl(inferTypes1.ts, 88, 33)) ->Y : Symbol(Y, Decl(inferTypes1.ts, 88, 42)) +>T77 : Symbol(T77, Decl(inferTypes1.ts, 95, 48)) +>T : Symbol(T, Decl(inferTypes1.ts, 96, 9)) +>T : Symbol(T, Decl(inferTypes1.ts, 96, 9)) +>T76 : Symbol(T76, Decl(inferTypes1.ts, 93, 84)) +>X : Symbol(X, Decl(inferTypes1.ts, 96, 33)) +>Y : Symbol(Y, Decl(inferTypes1.ts, 96, 42)) +>T76 : Symbol(T76, Decl(inferTypes1.ts, 93, 84)) +>X : Symbol(X, Decl(inferTypes1.ts, 96, 33)) +>Y : Symbol(Y, Decl(inferTypes1.ts, 96, 42)) type T78 = T extends T76 ? T76 : never; ->T78 : Symbol(T78, Decl(inferTypes1.ts, 88, 66)) ->T : Symbol(T, Decl(inferTypes1.ts, 89, 9)) ->T : Symbol(T, Decl(inferTypes1.ts, 89, 9)) ->T76 : Symbol(T76, Decl(inferTypes1.ts, 85, 84)) ->X : Symbol(X, Decl(inferTypes1.ts, 89, 33), Decl(inferTypes1.ts, 89, 42)) ->X : Symbol(X, Decl(inferTypes1.ts, 89, 33), Decl(inferTypes1.ts, 89, 42)) ->T76 : Symbol(T76, Decl(inferTypes1.ts, 85, 84)) ->X : Symbol(X, Decl(inferTypes1.ts, 89, 33), Decl(inferTypes1.ts, 89, 42)) ->X : Symbol(X, Decl(inferTypes1.ts, 89, 33), Decl(inferTypes1.ts, 89, 42)) +>T78 : Symbol(T78, Decl(inferTypes1.ts, 96, 66)) +>T : Symbol(T, Decl(inferTypes1.ts, 97, 9)) +>T : Symbol(T, Decl(inferTypes1.ts, 97, 9)) +>T76 : Symbol(T76, Decl(inferTypes1.ts, 93, 84)) +>X : Symbol(X, Decl(inferTypes1.ts, 97, 33), Decl(inferTypes1.ts, 97, 42)) +>X : Symbol(X, Decl(inferTypes1.ts, 97, 33), Decl(inferTypes1.ts, 97, 42)) +>T76 : Symbol(T76, Decl(inferTypes1.ts, 93, 84)) +>X : Symbol(X, Decl(inferTypes1.ts, 97, 33), Decl(inferTypes1.ts, 97, 42)) +>X : Symbol(X, Decl(inferTypes1.ts, 97, 33), Decl(inferTypes1.ts, 97, 42)) type Foo = [T, U]; ->Foo : Symbol(Foo, Decl(inferTypes1.ts, 89, 66)) ->T : Symbol(T, Decl(inferTypes1.ts, 91, 9)) ->U : Symbol(U, Decl(inferTypes1.ts, 91, 26)) ->T : Symbol(T, Decl(inferTypes1.ts, 91, 9)) ->T : Symbol(T, Decl(inferTypes1.ts, 91, 9)) ->U : Symbol(U, Decl(inferTypes1.ts, 91, 26)) +>Foo : Symbol(Foo, Decl(inferTypes1.ts, 97, 66)) +>T : Symbol(T, Decl(inferTypes1.ts, 99, 9)) +>U : Symbol(U, Decl(inferTypes1.ts, 99, 26)) +>T : Symbol(T, Decl(inferTypes1.ts, 99, 9)) +>T : Symbol(T, Decl(inferTypes1.ts, 99, 9)) +>U : Symbol(U, Decl(inferTypes1.ts, 99, 26)) type Bar = T extends Foo ? Foo : never; ->Bar : Symbol(Bar, Decl(inferTypes1.ts, 91, 49)) ->T : Symbol(T, Decl(inferTypes1.ts, 92, 9)) ->T : Symbol(T, Decl(inferTypes1.ts, 92, 9)) ->Foo : Symbol(Foo, Decl(inferTypes1.ts, 89, 66)) ->X : Symbol(X, Decl(inferTypes1.ts, 92, 33)) ->Y : Symbol(Y, Decl(inferTypes1.ts, 92, 42)) ->Foo : Symbol(Foo, Decl(inferTypes1.ts, 89, 66)) ->X : Symbol(X, Decl(inferTypes1.ts, 92, 33)) ->Y : Symbol(Y, Decl(inferTypes1.ts, 92, 42)) +>Bar : Symbol(Bar, Decl(inferTypes1.ts, 99, 49)) +>T : Symbol(T, Decl(inferTypes1.ts, 100, 9)) +>T : Symbol(T, Decl(inferTypes1.ts, 100, 9)) +>Foo : Symbol(Foo, Decl(inferTypes1.ts, 97, 66)) +>X : Symbol(X, Decl(inferTypes1.ts, 100, 33)) +>Y : Symbol(Y, Decl(inferTypes1.ts, 100, 42)) +>Foo : Symbol(Foo, Decl(inferTypes1.ts, 97, 66)) +>X : Symbol(X, Decl(inferTypes1.ts, 100, 33)) +>Y : Symbol(Y, Decl(inferTypes1.ts, 100, 42)) type T90 = Bar<[string, string]>; // [string, string] ->T90 : Symbol(T90, Decl(inferTypes1.ts, 92, 66)) ->Bar : Symbol(Bar, Decl(inferTypes1.ts, 91, 49)) +>T90 : Symbol(T90, Decl(inferTypes1.ts, 100, 66)) +>Bar : Symbol(Bar, Decl(inferTypes1.ts, 99, 49)) type T91 = Bar<[string, "a"]>; // [string, "a"] ->T91 : Symbol(T91, Decl(inferTypes1.ts, 94, 33)) ->Bar : Symbol(Bar, Decl(inferTypes1.ts, 91, 49)) +>T91 : Symbol(T91, Decl(inferTypes1.ts, 102, 33)) +>Bar : Symbol(Bar, Decl(inferTypes1.ts, 99, 49)) type T92 = Bar<[string, "a"] & { x: string }>; // [string, "a"] ->T92 : Symbol(T92, Decl(inferTypes1.ts, 95, 30)) ->Bar : Symbol(Bar, Decl(inferTypes1.ts, 91, 49)) ->x : Symbol(x, Decl(inferTypes1.ts, 96, 32)) +>T92 : Symbol(T92, Decl(inferTypes1.ts, 103, 30)) +>Bar : Symbol(Bar, Decl(inferTypes1.ts, 99, 49)) +>x : Symbol(x, Decl(inferTypes1.ts, 104, 32)) type T93 = Bar<["a", string]>; // never ->T93 : Symbol(T93, Decl(inferTypes1.ts, 96, 46)) ->Bar : Symbol(Bar, Decl(inferTypes1.ts, 91, 49)) +>T93 : Symbol(T93, Decl(inferTypes1.ts, 104, 46)) +>Bar : Symbol(Bar, Decl(inferTypes1.ts, 99, 49)) type T94 = Bar<[number, number]>; // never ->T94 : Symbol(T94, Decl(inferTypes1.ts, 97, 30)) ->Bar : Symbol(Bar, Decl(inferTypes1.ts, 91, 49)) +>T94 : Symbol(T94, Decl(inferTypes1.ts, 105, 30)) +>Bar : Symbol(Bar, Decl(inferTypes1.ts, 99, 49)) // Example from #21496 type JsonifiedObject = { [K in keyof T]: Jsonified }; ->JsonifiedObject : Symbol(JsonifiedObject, Decl(inferTypes1.ts, 98, 33)) ->T : Symbol(T, Decl(inferTypes1.ts, 102, 21)) ->K : Symbol(K, Decl(inferTypes1.ts, 102, 44)) ->T : Symbol(T, Decl(inferTypes1.ts, 102, 21)) ->Jsonified : Symbol(Jsonified, Decl(inferTypes1.ts, 102, 77)) ->T : Symbol(T, Decl(inferTypes1.ts, 102, 21)) ->K : Symbol(K, Decl(inferTypes1.ts, 102, 44)) +>JsonifiedObject : Symbol(JsonifiedObject, Decl(inferTypes1.ts, 106, 33)) +>T : Symbol(T, Decl(inferTypes1.ts, 110, 21)) +>K : Symbol(K, Decl(inferTypes1.ts, 110, 44)) +>T : Symbol(T, Decl(inferTypes1.ts, 110, 21)) +>Jsonified : Symbol(Jsonified, Decl(inferTypes1.ts, 110, 77)) +>T : Symbol(T, Decl(inferTypes1.ts, 110, 21)) +>K : Symbol(K, Decl(inferTypes1.ts, 110, 44)) type Jsonified = ->Jsonified : Symbol(Jsonified, Decl(inferTypes1.ts, 102, 77)) ->T : Symbol(T, Decl(inferTypes1.ts, 104, 15)) +>Jsonified : Symbol(Jsonified, Decl(inferTypes1.ts, 110, 77)) +>T : Symbol(T, Decl(inferTypes1.ts, 112, 15)) T extends string | number | boolean | null ? T ->T : Symbol(T, Decl(inferTypes1.ts, 104, 15)) ->T : Symbol(T, Decl(inferTypes1.ts, 104, 15)) +>T : Symbol(T, Decl(inferTypes1.ts, 112, 15)) +>T : Symbol(T, Decl(inferTypes1.ts, 112, 15)) : T extends undefined | Function ? never // undefined and functions are removed ->T : Symbol(T, Decl(inferTypes1.ts, 104, 15)) +>T : Symbol(T, Decl(inferTypes1.ts, 112, 15)) >Function : Symbol(Function, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) : T extends { toJSON(): infer R } ? R // toJSON is called if it exists (e.g. Date) ->T : Symbol(T, Decl(inferTypes1.ts, 104, 15)) ->toJSON : Symbol(toJSON, Decl(inferTypes1.ts, 107, 17)) ->R : Symbol(R, Decl(inferTypes1.ts, 107, 33)) ->R : Symbol(R, Decl(inferTypes1.ts, 107, 33)) +>T : Symbol(T, Decl(inferTypes1.ts, 112, 15)) +>toJSON : Symbol(toJSON, Decl(inferTypes1.ts, 115, 17)) +>R : Symbol(R, Decl(inferTypes1.ts, 115, 33)) +>R : Symbol(R, Decl(inferTypes1.ts, 115, 33)) : T extends object ? JsonifiedObject ->T : Symbol(T, Decl(inferTypes1.ts, 104, 15)) ->JsonifiedObject : Symbol(JsonifiedObject, Decl(inferTypes1.ts, 98, 33)) ->T : Symbol(T, Decl(inferTypes1.ts, 104, 15)) +>T : Symbol(T, Decl(inferTypes1.ts, 112, 15)) +>JsonifiedObject : Symbol(JsonifiedObject, Decl(inferTypes1.ts, 106, 33)) +>T : Symbol(T, Decl(inferTypes1.ts, 112, 15)) : "what is this"; type Example = { ->Example : Symbol(Example, Decl(inferTypes1.ts, 109, 21)) +>Example : Symbol(Example, Decl(inferTypes1.ts, 117, 21)) str: "literalstring", ->str : Symbol(str, Decl(inferTypes1.ts, 111, 16)) +>str : Symbol(str, Decl(inferTypes1.ts, 119, 16)) fn: () => void, ->fn : Symbol(fn, Decl(inferTypes1.ts, 112, 25)) +>fn : Symbol(fn, Decl(inferTypes1.ts, 120, 25)) date: Date, ->date : Symbol(date, Decl(inferTypes1.ts, 113, 19)) +>date : Symbol(date, Decl(inferTypes1.ts, 121, 19)) >Date : Symbol(Date, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.scripthost.d.ts, --, --)) customClass: MyClass, ->customClass : Symbol(customClass, Decl(inferTypes1.ts, 114, 15)) ->MyClass : Symbol(MyClass, Decl(inferTypes1.ts, 121, 1)) +>customClass : Symbol(customClass, Decl(inferTypes1.ts, 122, 15)) +>MyClass : Symbol(MyClass, Decl(inferTypes1.ts, 129, 1)) obj: { ->obj : Symbol(obj, Decl(inferTypes1.ts, 115, 25)) +>obj : Symbol(obj, Decl(inferTypes1.ts, 123, 25)) prop: "property", ->prop : Symbol(prop, Decl(inferTypes1.ts, 116, 10)) +>prop : Symbol(prop, Decl(inferTypes1.ts, 124, 10)) clz: MyClass, ->clz : Symbol(clz, Decl(inferTypes1.ts, 117, 25)) ->MyClass : Symbol(MyClass, Decl(inferTypes1.ts, 121, 1)) +>clz : Symbol(clz, Decl(inferTypes1.ts, 125, 25)) +>MyClass : Symbol(MyClass, Decl(inferTypes1.ts, 129, 1)) nested: { attr: Date } ->nested : Symbol(nested, Decl(inferTypes1.ts, 118, 21)) ->attr : Symbol(attr, Decl(inferTypes1.ts, 119, 17)) +>nested : Symbol(nested, Decl(inferTypes1.ts, 126, 21)) +>attr : Symbol(attr, Decl(inferTypes1.ts, 127, 17)) >Date : Symbol(Date, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.scripthost.d.ts, --, --)) }, } declare class MyClass { ->MyClass : Symbol(MyClass, Decl(inferTypes1.ts, 121, 1)) +>MyClass : Symbol(MyClass, Decl(inferTypes1.ts, 129, 1)) toJSON(): "correct"; ->toJSON : Symbol(MyClass.toJSON, Decl(inferTypes1.ts, 123, 23)) +>toJSON : Symbol(MyClass.toJSON, Decl(inferTypes1.ts, 131, 23)) } type JsonifiedExample = Jsonified; ->JsonifiedExample : Symbol(JsonifiedExample, Decl(inferTypes1.ts, 125, 1)) ->Jsonified : Symbol(Jsonified, Decl(inferTypes1.ts, 102, 77)) ->Example : Symbol(Example, Decl(inferTypes1.ts, 109, 21)) +>JsonifiedExample : Symbol(JsonifiedExample, Decl(inferTypes1.ts, 133, 1)) +>Jsonified : Symbol(Jsonified, Decl(inferTypes1.ts, 110, 77)) +>Example : Symbol(Example, Decl(inferTypes1.ts, 117, 21)) declare let ex: JsonifiedExample; ->ex : Symbol(ex, Decl(inferTypes1.ts, 128, 11)) ->JsonifiedExample : Symbol(JsonifiedExample, Decl(inferTypes1.ts, 125, 1)) +>ex : Symbol(ex, Decl(inferTypes1.ts, 136, 11)) +>JsonifiedExample : Symbol(JsonifiedExample, Decl(inferTypes1.ts, 133, 1)) const z1: "correct" = ex.customClass; ->z1 : Symbol(z1, Decl(inferTypes1.ts, 129, 5)) ->ex.customClass : Symbol(customClass, Decl(inferTypes1.ts, 114, 15)) ->ex : Symbol(ex, Decl(inferTypes1.ts, 128, 11)) ->customClass : Symbol(customClass, Decl(inferTypes1.ts, 114, 15)) +>z1 : Symbol(z1, Decl(inferTypes1.ts, 137, 5)) +>ex.customClass : Symbol(customClass, Decl(inferTypes1.ts, 122, 15)) +>ex : Symbol(ex, Decl(inferTypes1.ts, 136, 11)) +>customClass : Symbol(customClass, Decl(inferTypes1.ts, 122, 15)) const z2: string = ex.obj.nested.attr; ->z2 : Symbol(z2, Decl(inferTypes1.ts, 130, 5)) ->ex.obj.nested.attr : Symbol(attr, Decl(inferTypes1.ts, 119, 17)) ->ex.obj.nested : Symbol(nested, Decl(inferTypes1.ts, 118, 21)) ->ex.obj : Symbol(obj, Decl(inferTypes1.ts, 115, 25)) ->ex : Symbol(ex, Decl(inferTypes1.ts, 128, 11)) ->obj : Symbol(obj, Decl(inferTypes1.ts, 115, 25)) ->nested : Symbol(nested, Decl(inferTypes1.ts, 118, 21)) ->attr : Symbol(attr, Decl(inferTypes1.ts, 119, 17)) +>z2 : Symbol(z2, Decl(inferTypes1.ts, 138, 5)) +>ex.obj.nested.attr : Symbol(attr, Decl(inferTypes1.ts, 127, 17)) +>ex.obj.nested : Symbol(nested, Decl(inferTypes1.ts, 126, 21)) +>ex.obj : Symbol(obj, Decl(inferTypes1.ts, 123, 25)) +>ex : Symbol(ex, Decl(inferTypes1.ts, 136, 11)) +>obj : Symbol(obj, Decl(inferTypes1.ts, 123, 25)) +>nested : Symbol(nested, Decl(inferTypes1.ts, 126, 21)) +>attr : Symbol(attr, Decl(inferTypes1.ts, 127, 17)) // Repros from #21631 type A1> = [T, U]; ->A1 : Symbol(A1, Decl(inferTypes1.ts, 130, 38)) ->T : Symbol(T, Decl(inferTypes1.ts, 134, 8)) ->U : Symbol(U, Decl(inferTypes1.ts, 134, 10)) ->A1 : Symbol(A1, Decl(inferTypes1.ts, 130, 38)) ->T : Symbol(T, Decl(inferTypes1.ts, 134, 8)) ->U : Symbol(U, Decl(inferTypes1.ts, 134, 10)) +>A1 : Symbol(A1, Decl(inferTypes1.ts, 138, 38)) +>T : Symbol(T, Decl(inferTypes1.ts, 142, 8)) +>U : Symbol(U, Decl(inferTypes1.ts, 142, 10)) +>A1 : Symbol(A1, Decl(inferTypes1.ts, 138, 38)) +>T : Symbol(T, Decl(inferTypes1.ts, 142, 8)) +>U : Symbol(U, Decl(inferTypes1.ts, 142, 10)) type B1 = S extends A1 ? [T, U] : never; ->B1 : Symbol(B1, Decl(inferTypes1.ts, 134, 44)) ->S : Symbol(S, Decl(inferTypes1.ts, 135, 8)) ->S : Symbol(S, Decl(inferTypes1.ts, 135, 8)) ->A1 : Symbol(A1, Decl(inferTypes1.ts, 130, 38)) ->T : Symbol(T, Decl(inferTypes1.ts, 135, 31)) ->U : Symbol(U, Decl(inferTypes1.ts, 135, 40)) ->T : Symbol(T, Decl(inferTypes1.ts, 135, 31)) ->U : Symbol(U, Decl(inferTypes1.ts, 135, 40)) +>B1 : Symbol(B1, Decl(inferTypes1.ts, 142, 44)) +>S : Symbol(S, Decl(inferTypes1.ts, 143, 8)) +>S : Symbol(S, Decl(inferTypes1.ts, 143, 8)) +>A1 : Symbol(A1, Decl(inferTypes1.ts, 138, 38)) +>T : Symbol(T, Decl(inferTypes1.ts, 143, 31)) +>U : Symbol(U, Decl(inferTypes1.ts, 143, 40)) +>T : Symbol(T, Decl(inferTypes1.ts, 143, 31)) +>U : Symbol(U, Decl(inferTypes1.ts, 143, 40)) type A2 = [T, U]; ->A2 : Symbol(A2, Decl(inferTypes1.ts, 135, 61)) ->T : Symbol(T, Decl(inferTypes1.ts, 137, 8)) ->U : Symbol(U, Decl(inferTypes1.ts, 137, 10)) ->T : Symbol(T, Decl(inferTypes1.ts, 137, 8)) ->U : Symbol(U, Decl(inferTypes1.ts, 137, 10)) +>A2 : Symbol(A2, Decl(inferTypes1.ts, 143, 61)) +>T : Symbol(T, Decl(inferTypes1.ts, 145, 8)) +>U : Symbol(U, Decl(inferTypes1.ts, 145, 10)) +>T : Symbol(T, Decl(inferTypes1.ts, 145, 8)) +>U : Symbol(U, Decl(inferTypes1.ts, 145, 10)) type B2 = S extends A2 ? [T, U] : never; ->B2 : Symbol(B2, Decl(inferTypes1.ts, 137, 36)) ->S : Symbol(S, Decl(inferTypes1.ts, 138, 8)) ->S : Symbol(S, Decl(inferTypes1.ts, 138, 8)) ->A2 : Symbol(A2, Decl(inferTypes1.ts, 135, 61)) ->T : Symbol(T, Decl(inferTypes1.ts, 138, 31)) ->U : Symbol(U, Decl(inferTypes1.ts, 138, 40)) ->T : Symbol(T, Decl(inferTypes1.ts, 138, 31)) ->U : Symbol(U, Decl(inferTypes1.ts, 138, 40)) +>B2 : Symbol(B2, Decl(inferTypes1.ts, 145, 36)) +>S : Symbol(S, Decl(inferTypes1.ts, 146, 8)) +>S : Symbol(S, Decl(inferTypes1.ts, 146, 8)) +>A2 : Symbol(A2, Decl(inferTypes1.ts, 143, 61)) +>T : Symbol(T, Decl(inferTypes1.ts, 146, 31)) +>U : Symbol(U, Decl(inferTypes1.ts, 146, 40)) +>T : Symbol(T, Decl(inferTypes1.ts, 146, 31)) +>U : Symbol(U, Decl(inferTypes1.ts, 146, 40)) type C2 = S extends A2 ? [T, U] : never; ->C2 : Symbol(C2, Decl(inferTypes1.ts, 138, 61)) ->S : Symbol(S, Decl(inferTypes1.ts, 139, 8)) ->U : Symbol(U, Decl(inferTypes1.ts, 139, 10)) ->S : Symbol(S, Decl(inferTypes1.ts, 139, 8)) ->A2 : Symbol(A2, Decl(inferTypes1.ts, 135, 61)) ->T : Symbol(T, Decl(inferTypes1.ts, 139, 47)) ->U : Symbol(U, Decl(inferTypes1.ts, 139, 10)) ->T : Symbol(T, Decl(inferTypes1.ts, 139, 47)) ->U : Symbol(U, Decl(inferTypes1.ts, 139, 10)) +>C2 : Symbol(C2, Decl(inferTypes1.ts, 146, 61)) +>S : Symbol(S, Decl(inferTypes1.ts, 147, 8)) +>U : Symbol(U, Decl(inferTypes1.ts, 147, 10)) +>S : Symbol(S, Decl(inferTypes1.ts, 147, 8)) +>A2 : Symbol(A2, Decl(inferTypes1.ts, 143, 61)) +>T : Symbol(T, Decl(inferTypes1.ts, 147, 47)) +>U : Symbol(U, Decl(inferTypes1.ts, 147, 10)) +>T : Symbol(T, Decl(inferTypes1.ts, 147, 47)) +>U : Symbol(U, Decl(inferTypes1.ts, 147, 10)) // Repro from #21735 type A = T extends string ? { [P in T]: void; } : T; ->A : Symbol(A, Decl(inferTypes1.ts, 139, 71)) ->T : Symbol(T, Decl(inferTypes1.ts, 143, 7)) ->T : Symbol(T, Decl(inferTypes1.ts, 143, 7)) ->P : Symbol(P, Decl(inferTypes1.ts, 143, 34)) ->T : Symbol(T, Decl(inferTypes1.ts, 143, 7)) ->T : Symbol(T, Decl(inferTypes1.ts, 143, 7)) +>A : Symbol(A, Decl(inferTypes1.ts, 147, 71)) +>T : Symbol(T, Decl(inferTypes1.ts, 151, 7)) +>T : Symbol(T, Decl(inferTypes1.ts, 151, 7)) +>P : Symbol(P, Decl(inferTypes1.ts, 151, 34)) +>T : Symbol(T, Decl(inferTypes1.ts, 151, 7)) +>T : Symbol(T, Decl(inferTypes1.ts, 151, 7)) type B = string extends T ? { [P in T]: void; } : T; // Error ->B : Symbol(B, Decl(inferTypes1.ts, 143, 55)) ->T : Symbol(T, Decl(inferTypes1.ts, 144, 7)) ->T : Symbol(T, Decl(inferTypes1.ts, 144, 7)) ->P : Symbol(P, Decl(inferTypes1.ts, 144, 34)) ->T : Symbol(T, Decl(inferTypes1.ts, 144, 7)) ->T : Symbol(T, Decl(inferTypes1.ts, 144, 7)) +>B : Symbol(B, Decl(inferTypes1.ts, 151, 55)) +>T : Symbol(T, Decl(inferTypes1.ts, 152, 7)) +>T : Symbol(T, Decl(inferTypes1.ts, 152, 7)) +>P : Symbol(P, Decl(inferTypes1.ts, 152, 34)) +>T : Symbol(T, Decl(inferTypes1.ts, 152, 7)) +>T : Symbol(T, Decl(inferTypes1.ts, 152, 7)) // Repro from #22302 type MatchingKeys = ->MatchingKeys : Symbol(MatchingKeys, Decl(inferTypes1.ts, 144, 55)) ->T : Symbol(T, Decl(inferTypes1.ts, 148, 18)) ->U : Symbol(U, Decl(inferTypes1.ts, 148, 20)) ->K : Symbol(K, Decl(inferTypes1.ts, 148, 23)) ->T : Symbol(T, Decl(inferTypes1.ts, 148, 18)) ->T : Symbol(T, Decl(inferTypes1.ts, 148, 18)) +>MatchingKeys : Symbol(MatchingKeys, Decl(inferTypes1.ts, 152, 55)) +>T : Symbol(T, Decl(inferTypes1.ts, 156, 18)) +>U : Symbol(U, Decl(inferTypes1.ts, 156, 20)) +>K : Symbol(K, Decl(inferTypes1.ts, 156, 23)) +>T : Symbol(T, Decl(inferTypes1.ts, 156, 18)) +>T : Symbol(T, Decl(inferTypes1.ts, 156, 18)) K extends keyof T ? T[K] extends U ? K : never : never; ->K : Symbol(K, Decl(inferTypes1.ts, 148, 23)) ->T : Symbol(T, Decl(inferTypes1.ts, 148, 18)) ->T : Symbol(T, Decl(inferTypes1.ts, 148, 18)) ->K : Symbol(K, Decl(inferTypes1.ts, 148, 23)) ->U : Symbol(U, Decl(inferTypes1.ts, 148, 20)) ->K : Symbol(K, Decl(inferTypes1.ts, 148, 23)) +>K : Symbol(K, Decl(inferTypes1.ts, 156, 23)) +>T : Symbol(T, Decl(inferTypes1.ts, 156, 18)) +>T : Symbol(T, Decl(inferTypes1.ts, 156, 18)) +>K : Symbol(K, Decl(inferTypes1.ts, 156, 23)) +>U : Symbol(U, Decl(inferTypes1.ts, 156, 20)) +>K : Symbol(K, Decl(inferTypes1.ts, 156, 23)) type VoidKeys = MatchingKeys; ->VoidKeys : Symbol(VoidKeys, Decl(inferTypes1.ts, 149, 59)) ->T : Symbol(T, Decl(inferTypes1.ts, 151, 14)) ->MatchingKeys : Symbol(MatchingKeys, Decl(inferTypes1.ts, 144, 55)) ->T : Symbol(T, Decl(inferTypes1.ts, 151, 14)) +>VoidKeys : Symbol(VoidKeys, Decl(inferTypes1.ts, 157, 59)) +>T : Symbol(T, Decl(inferTypes1.ts, 159, 14)) +>MatchingKeys : Symbol(MatchingKeys, Decl(inferTypes1.ts, 152, 55)) +>T : Symbol(T, Decl(inferTypes1.ts, 159, 14)) interface test { ->test : Symbol(test, Decl(inferTypes1.ts, 151, 41)) +>test : Symbol(test, Decl(inferTypes1.ts, 159, 41)) a: 1, ->a : Symbol(test.a, Decl(inferTypes1.ts, 153, 16)) +>a : Symbol(test.a, Decl(inferTypes1.ts, 161, 16)) b: void ->b : Symbol(test.b, Decl(inferTypes1.ts, 154, 9)) +>b : Symbol(test.b, Decl(inferTypes1.ts, 162, 9)) } type T80 = MatchingKeys; ->T80 : Symbol(T80, Decl(inferTypes1.ts, 156, 1)) ->MatchingKeys : Symbol(MatchingKeys, Decl(inferTypes1.ts, 144, 55)) ->test : Symbol(test, Decl(inferTypes1.ts, 151, 41)) +>T80 : Symbol(T80, Decl(inferTypes1.ts, 164, 1)) +>MatchingKeys : Symbol(MatchingKeys, Decl(inferTypes1.ts, 152, 55)) +>test : Symbol(test, Decl(inferTypes1.ts, 159, 41)) type T81 = VoidKeys; ->T81 : Symbol(T81, Decl(inferTypes1.ts, 158, 36)) ->VoidKeys : Symbol(VoidKeys, Decl(inferTypes1.ts, 149, 59)) ->test : Symbol(test, Decl(inferTypes1.ts, 151, 41)) +>T81 : Symbol(T81, Decl(inferTypes1.ts, 166, 36)) +>VoidKeys : Symbol(VoidKeys, Decl(inferTypes1.ts, 157, 59)) +>test : Symbol(test, Decl(inferTypes1.ts, 159, 41)) // Repro from #22221 type MustBeString = T; ->MustBeString : Symbol(MustBeString, Decl(inferTypes1.ts, 159, 26)) ->T : Symbol(T, Decl(inferTypes1.ts, 163, 18)) ->T : Symbol(T, Decl(inferTypes1.ts, 163, 18)) +>MustBeString : Symbol(MustBeString, Decl(inferTypes1.ts, 167, 26)) +>T : Symbol(T, Decl(inferTypes1.ts, 171, 18)) +>T : Symbol(T, Decl(inferTypes1.ts, 171, 18)) type EnsureIsString = T extends MustBeString ? U : never; ->EnsureIsString : Symbol(EnsureIsString, Decl(inferTypes1.ts, 163, 40)) ->T : Symbol(T, Decl(inferTypes1.ts, 164, 20)) ->T : Symbol(T, Decl(inferTypes1.ts, 164, 20)) ->MustBeString : Symbol(MustBeString, Decl(inferTypes1.ts, 159, 26)) ->U : Symbol(U, Decl(inferTypes1.ts, 164, 53)) ->U : Symbol(U, Decl(inferTypes1.ts, 164, 53)) +>EnsureIsString : Symbol(EnsureIsString, Decl(inferTypes1.ts, 171, 40)) +>T : Symbol(T, Decl(inferTypes1.ts, 172, 20)) +>T : Symbol(T, Decl(inferTypes1.ts, 172, 20)) +>MustBeString : Symbol(MustBeString, Decl(inferTypes1.ts, 167, 26)) +>U : Symbol(U, Decl(inferTypes1.ts, 172, 53)) +>U : Symbol(U, Decl(inferTypes1.ts, 172, 53)) type Test1 = EnsureIsString<"hello">; // "hello" ->Test1 : Symbol(Test1, Decl(inferTypes1.ts, 164, 69)) ->EnsureIsString : Symbol(EnsureIsString, Decl(inferTypes1.ts, 163, 40)) +>Test1 : Symbol(Test1, Decl(inferTypes1.ts, 172, 69)) +>EnsureIsString : Symbol(EnsureIsString, Decl(inferTypes1.ts, 171, 40)) type Test2 = EnsureIsString<42>; // never ->Test2 : Symbol(Test2, Decl(inferTypes1.ts, 166, 37)) ->EnsureIsString : Symbol(EnsureIsString, Decl(inferTypes1.ts, 163, 40)) +>Test2 : Symbol(Test2, Decl(inferTypes1.ts, 174, 37)) +>EnsureIsString : Symbol(EnsureIsString, Decl(inferTypes1.ts, 171, 40)) // Repros from #26856 function invoker (key: K, ...args: A) { ->invoker : Symbol(invoker, Decl(inferTypes1.ts, 167, 32)) ->K : Symbol(K, Decl(inferTypes1.ts, 171, 18)) ->A : Symbol(A, Decl(inferTypes1.ts, 171, 53)) ->key : Symbol(key, Decl(inferTypes1.ts, 171, 72)) ->K : Symbol(K, Decl(inferTypes1.ts, 171, 18)) ->args : Symbol(args, Decl(inferTypes1.ts, 171, 79)) ->A : Symbol(A, Decl(inferTypes1.ts, 171, 53)) +>invoker : Symbol(invoker, Decl(inferTypes1.ts, 175, 32)) +>K : Symbol(K, Decl(inferTypes1.ts, 179, 18)) +>A : Symbol(A, Decl(inferTypes1.ts, 179, 53)) +>key : Symbol(key, Decl(inferTypes1.ts, 179, 72)) +>K : Symbol(K, Decl(inferTypes1.ts, 179, 18)) +>args : Symbol(args, Decl(inferTypes1.ts, 179, 79)) +>A : Symbol(A, Decl(inferTypes1.ts, 179, 53)) return any>> (obj: T): ReturnType => obj[key](...args) ->T : Symbol(T, Decl(inferTypes1.ts, 172, 12)) +>T : Symbol(T, Decl(inferTypes1.ts, 180, 12)) >Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) ->K : Symbol(K, Decl(inferTypes1.ts, 171, 18)) ->args : Symbol(args, Decl(inferTypes1.ts, 172, 33)) ->A : Symbol(A, Decl(inferTypes1.ts, 171, 53)) ->obj : Symbol(obj, Decl(inferTypes1.ts, 172, 55)) ->T : Symbol(T, Decl(inferTypes1.ts, 172, 12)) +>K : Symbol(K, Decl(inferTypes1.ts, 179, 18)) +>args : Symbol(args, Decl(inferTypes1.ts, 180, 33)) +>A : Symbol(A, Decl(inferTypes1.ts, 179, 53)) +>obj : Symbol(obj, Decl(inferTypes1.ts, 180, 55)) +>T : Symbol(T, Decl(inferTypes1.ts, 180, 12)) >ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) ->T : Symbol(T, Decl(inferTypes1.ts, 172, 12)) ->K : Symbol(K, Decl(inferTypes1.ts, 171, 18)) ->obj : Symbol(obj, Decl(inferTypes1.ts, 172, 55)) ->key : Symbol(key, Decl(inferTypes1.ts, 171, 72)) ->args : Symbol(args, Decl(inferTypes1.ts, 171, 79)) +>T : Symbol(T, Decl(inferTypes1.ts, 180, 12)) +>K : Symbol(K, Decl(inferTypes1.ts, 179, 18)) +>obj : Symbol(obj, Decl(inferTypes1.ts, 180, 55)) +>key : Symbol(key, Decl(inferTypes1.ts, 179, 72)) +>args : Symbol(args, Decl(inferTypes1.ts, 179, 79)) } const result = invoker('test', true)({ test: (a: boolean) => 123 }) ->result : Symbol(result, Decl(inferTypes1.ts, 175, 5)) ->invoker : Symbol(invoker, Decl(inferTypes1.ts, 167, 32)) ->test : Symbol(test, Decl(inferTypes1.ts, 175, 38)) ->a : Symbol(a, Decl(inferTypes1.ts, 175, 46)) +>result : Symbol(result, Decl(inferTypes1.ts, 183, 5)) +>invoker : Symbol(invoker, Decl(inferTypes1.ts, 175, 32)) +>test : Symbol(test, Decl(inferTypes1.ts, 183, 38)) +>a : Symbol(a, Decl(inferTypes1.ts, 183, 46)) type Foo2 = ReturnType<(...args: A) => string>; ->Foo2 : Symbol(Foo2, Decl(inferTypes1.ts, 175, 67)) ->A : Symbol(A, Decl(inferTypes1.ts, 177, 10)) +>Foo2 : Symbol(Foo2, Decl(inferTypes1.ts, 183, 67)) +>A : Symbol(A, Decl(inferTypes1.ts, 185, 10)) >ReturnType : Symbol(ReturnType, Decl(lib.es5.d.ts, --, --)) ->args : Symbol(args, Decl(inferTypes1.ts, 177, 41)) ->A : Symbol(A, Decl(inferTypes1.ts, 177, 10)) +>args : Symbol(args, Decl(inferTypes1.ts, 185, 41)) +>A : Symbol(A, Decl(inferTypes1.ts, 185, 10)) diff --git a/tests/baselines/reference/inferTypes1.types b/tests/baselines/reference/inferTypes1.types index aa421dd4c4d76..66e4c00ccbbdc 100644 --- a/tests/baselines/reference/inferTypes1.types +++ b/tests/baselines/reference/inferTypes1.types @@ -54,6 +54,18 @@ class C { >0 : 0 } +abstract class Abstract { +>Abstract : Abstract + + x = 0; +>x : number +>0 : 0 + + y = 0; +>y : number +>0 : 0 +} + type T10 = ReturnType<() => string>; // string >T10 : string @@ -104,6 +116,20 @@ type U13 = InstanceType; // Error type U14 = InstanceType; // Error >U14 : any +type U15 = InstanceType; // Abstract +>U15 : any +>Abstract : typeof Abstract + +type U16 = InstanceType T[]>; // T[] +>U16 : T[] +>x : string +>args : T + +type U17 = InstanceType T[]>; // T[] +>U17 : any +>x : string +>args : T + type ArgumentType any> = T extends (a: infer A) => any ? A : any; >ArgumentType : ArgumentType >x : any diff --git a/tests/baselines/reference/mixinAbstractClasses.2.errors.txt b/tests/baselines/reference/mixinAbstractClasses.2.errors.txt new file mode 100644 index 0000000000000..99a92c854628c --- /dev/null +++ b/tests/baselines/reference/mixinAbstractClasses.2.errors.txt @@ -0,0 +1,37 @@ +tests/cases/conformance/classes/mixinAbstractClasses.2.ts(7,11): error TS2797: A mixin class that extends from a type variable containing an abstract construct signature must also be declared 'abstract'. +tests/cases/conformance/classes/mixinAbstractClasses.2.ts(21,7): error TS2515: Non-abstract class 'DerivedFromAbstract' does not implement inherited abstract member 'abstractBaseMethod' from class 'AbstractBase & Mixin'. +tests/cases/conformance/classes/mixinAbstractClasses.2.ts(25,1): error TS2511: Cannot create an instance of an abstract class. + + +==== tests/cases/conformance/classes/mixinAbstractClasses.2.ts (3 errors) ==== + interface Mixin { + mixinMethod(): void; + } + + function Mixin any>(baseClass: TBaseClass): TBaseClass & (abstract new (...args: any) => Mixin) { + // error expected: A mixin class that extends from a type variable containing an abstract construct signature must also be declared 'abstract'. + class MixinClass extends baseClass implements Mixin { + ~~~~~~~~~~ +!!! error TS2797: A mixin class that extends from a type variable containing an abstract construct signature must also be declared 'abstract'. + mixinMethod() { + } + } + return MixinClass; + } + + abstract class AbstractBase { + abstract abstractBaseMethod(): void; + } + + const MixedBase = Mixin(AbstractBase); + + // error expected: Non-abstract class 'DerivedFromAbstract' does not implement inherited abstract member 'abstractBaseMethod' from class 'AbstractBase & Mixin'. + class DerivedFromAbstract extends MixedBase { + ~~~~~~~~~~~~~~~~~~~ +!!! error TS2515: Non-abstract class 'DerivedFromAbstract' does not implement inherited abstract member 'abstractBaseMethod' from class 'AbstractBase & Mixin'. + } + + // error expected: Cannot create an instance of an abstract class. + new MixedBase(); + ~~~~~~~~~~~~~~~ +!!! error TS2511: Cannot create an instance of an abstract class. \ No newline at end of file diff --git a/tests/baselines/reference/mixinAbstractClasses.2.js b/tests/baselines/reference/mixinAbstractClasses.2.js new file mode 100644 index 0000000000000..b91e82763853f --- /dev/null +++ b/tests/baselines/reference/mixinAbstractClasses.2.js @@ -0,0 +1,57 @@ +//// [mixinAbstractClasses.2.ts] +interface Mixin { + mixinMethod(): void; +} + +function Mixin any>(baseClass: TBaseClass): TBaseClass & (abstract new (...args: any) => Mixin) { + // error expected: A mixin class that extends from a type variable containing an abstract construct signature must also be declared 'abstract'. + class MixinClass extends baseClass implements Mixin { + mixinMethod() { + } + } + return MixinClass; +} + +abstract class AbstractBase { + abstract abstractBaseMethod(): void; +} + +const MixedBase = Mixin(AbstractBase); + +// error expected: Non-abstract class 'DerivedFromAbstract' does not implement inherited abstract member 'abstractBaseMethod' from class 'AbstractBase & Mixin'. +class DerivedFromAbstract extends MixedBase { +} + +// error expected: Cannot create an instance of an abstract class. +new MixedBase(); + +//// [mixinAbstractClasses.2.js] +function Mixin(baseClass) { + // error expected: A mixin class that extends from a type variable containing an abstract construct signature must also be declared 'abstract'. + class MixinClass extends baseClass { + mixinMethod() { + } + } + return MixinClass; +} +class AbstractBase { +} +const MixedBase = Mixin(AbstractBase); +// error expected: Non-abstract class 'DerivedFromAbstract' does not implement inherited abstract member 'abstractBaseMethod' from class 'AbstractBase & Mixin'. +class DerivedFromAbstract extends MixedBase { +} +// error expected: Cannot create an instance of an abstract class. +new MixedBase(); + + +//// [mixinAbstractClasses.2.d.ts] +interface Mixin { + mixinMethod(): void; +} +declare function Mixin any>(baseClass: TBaseClass): TBaseClass & (abstract new (...args: any) => Mixin); +declare abstract class AbstractBase { + abstract abstractBaseMethod(): void; +} +declare const MixedBase: typeof AbstractBase & (abstract new (...args: any) => Mixin); +declare class DerivedFromAbstract extends MixedBase { +} diff --git a/tests/baselines/reference/mixinAbstractClasses.2.symbols b/tests/baselines/reference/mixinAbstractClasses.2.symbols new file mode 100644 index 0000000000000..194e88addc3d2 --- /dev/null +++ b/tests/baselines/reference/mixinAbstractClasses.2.symbols @@ -0,0 +1,54 @@ +=== tests/cases/conformance/classes/mixinAbstractClasses.2.ts === +interface Mixin { +>Mixin : Symbol(Mixin, Decl(mixinAbstractClasses.2.ts, 2, 1), Decl(mixinAbstractClasses.2.ts, 0, 0)) + + mixinMethod(): void; +>mixinMethod : Symbol(Mixin.mixinMethod, Decl(mixinAbstractClasses.2.ts, 0, 17)) +} + +function Mixin any>(baseClass: TBaseClass): TBaseClass & (abstract new (...args: any) => Mixin) { +>Mixin : Symbol(Mixin, Decl(mixinAbstractClasses.2.ts, 2, 1), Decl(mixinAbstractClasses.2.ts, 0, 0)) +>TBaseClass : Symbol(TBaseClass, Decl(mixinAbstractClasses.2.ts, 4, 15)) +>args : Symbol(args, Decl(mixinAbstractClasses.2.ts, 4, 48)) +>baseClass : Symbol(baseClass, Decl(mixinAbstractClasses.2.ts, 4, 70)) +>TBaseClass : Symbol(TBaseClass, Decl(mixinAbstractClasses.2.ts, 4, 15)) +>TBaseClass : Symbol(TBaseClass, Decl(mixinAbstractClasses.2.ts, 4, 15)) +>args : Symbol(args, Decl(mixinAbstractClasses.2.ts, 4, 122)) +>Mixin : Symbol(Mixin, Decl(mixinAbstractClasses.2.ts, 2, 1), Decl(mixinAbstractClasses.2.ts, 0, 0)) + + // error expected: A mixin class that extends from a type variable containing an abstract construct signature must also be declared 'abstract'. + class MixinClass extends baseClass implements Mixin { +>MixinClass : Symbol(MixinClass, Decl(mixinAbstractClasses.2.ts, 4, 147)) +>baseClass : Symbol(baseClass, Decl(mixinAbstractClasses.2.ts, 4, 70)) +>Mixin : Symbol(Mixin, Decl(mixinAbstractClasses.2.ts, 2, 1), Decl(mixinAbstractClasses.2.ts, 0, 0)) + + mixinMethod() { +>mixinMethod : Symbol(MixinClass.mixinMethod, Decl(mixinAbstractClasses.2.ts, 6, 57)) + } + } + return MixinClass; +>MixinClass : Symbol(MixinClass, Decl(mixinAbstractClasses.2.ts, 4, 147)) +} + +abstract class AbstractBase { +>AbstractBase : Symbol(AbstractBase, Decl(mixinAbstractClasses.2.ts, 11, 1)) + + abstract abstractBaseMethod(): void; +>abstractBaseMethod : Symbol(AbstractBase.abstractBaseMethod, Decl(mixinAbstractClasses.2.ts, 13, 29)) +} + +const MixedBase = Mixin(AbstractBase); +>MixedBase : Symbol(MixedBase, Decl(mixinAbstractClasses.2.ts, 17, 5)) +>Mixin : Symbol(Mixin, Decl(mixinAbstractClasses.2.ts, 2, 1), Decl(mixinAbstractClasses.2.ts, 0, 0)) +>AbstractBase : Symbol(AbstractBase, Decl(mixinAbstractClasses.2.ts, 11, 1)) + +// error expected: Non-abstract class 'DerivedFromAbstract' does not implement inherited abstract member 'abstractBaseMethod' from class 'AbstractBase & Mixin'. +class DerivedFromAbstract extends MixedBase { +>DerivedFromAbstract : Symbol(DerivedFromAbstract, Decl(mixinAbstractClasses.2.ts, 17, 38)) +>MixedBase : Symbol(MixedBase, Decl(mixinAbstractClasses.2.ts, 17, 5)) +} + +// error expected: Cannot create an instance of an abstract class. +new MixedBase(); +>MixedBase : Symbol(MixedBase, Decl(mixinAbstractClasses.2.ts, 17, 5)) + diff --git a/tests/baselines/reference/mixinAbstractClasses.2.types b/tests/baselines/reference/mixinAbstractClasses.2.types new file mode 100644 index 0000000000000..cb2bbe7e605fc --- /dev/null +++ b/tests/baselines/reference/mixinAbstractClasses.2.types @@ -0,0 +1,49 @@ +=== tests/cases/conformance/classes/mixinAbstractClasses.2.ts === +interface Mixin { + mixinMethod(): void; +>mixinMethod : () => void +} + +function Mixin any>(baseClass: TBaseClass): TBaseClass & (abstract new (...args: any) => Mixin) { +>Mixin : any>(baseClass: TBaseClass) => TBaseClass & (abstract new (...args: any) => Mixin) +>args : any +>baseClass : TBaseClass +>args : any + + // error expected: A mixin class that extends from a type variable containing an abstract construct signature must also be declared 'abstract'. + class MixinClass extends baseClass implements Mixin { +>MixinClass : MixinClass +>baseClass : TBaseClass + + mixinMethod() { +>mixinMethod : () => void + } + } + return MixinClass; +>MixinClass : { new (...args: any): MixinClass; prototype: Mixin.MixinClass; } & TBaseClass +} + +abstract class AbstractBase { +>AbstractBase : AbstractBase + + abstract abstractBaseMethod(): void; +>abstractBaseMethod : () => void +} + +const MixedBase = Mixin(AbstractBase); +>MixedBase : typeof AbstractBase & (abstract new (...args: any) => Mixin) +>Mixin(AbstractBase) : typeof AbstractBase & (abstract new (...args: any) => Mixin) +>Mixin : any>(baseClass: TBaseClass) => TBaseClass & (abstract new (...args: any) => Mixin) +>AbstractBase : typeof AbstractBase + +// error expected: Non-abstract class 'DerivedFromAbstract' does not implement inherited abstract member 'abstractBaseMethod' from class 'AbstractBase & Mixin'. +class DerivedFromAbstract extends MixedBase { +>DerivedFromAbstract : DerivedFromAbstract +>MixedBase : AbstractBase & Mixin +} + +// error expected: Cannot create an instance of an abstract class. +new MixedBase(); +>new MixedBase() : any +>MixedBase : typeof AbstractBase & (abstract new (...args: any) => Mixin) + diff --git a/tests/baselines/reference/mixinAbstractClasses.js b/tests/baselines/reference/mixinAbstractClasses.js new file mode 100644 index 0000000000000..3c887a087fbdc --- /dev/null +++ b/tests/baselines/reference/mixinAbstractClasses.js @@ -0,0 +1,82 @@ +//// [mixinAbstractClasses.ts] +interface Mixin { + mixinMethod(): void; +} + +function Mixin any>(baseClass: TBaseClass): TBaseClass & (abstract new (...args: any) => Mixin) { + abstract class MixinClass extends baseClass implements Mixin { + mixinMethod() { + } + } + return MixinClass; +} + +class ConcreteBase { + baseMethod() {} +} + +abstract class AbstractBase { + abstract abstractBaseMethod(): void; +} + +class DerivedFromConcrete extends Mixin(ConcreteBase) { +} + +const wasConcrete = new DerivedFromConcrete(); +wasConcrete.baseMethod(); +wasConcrete.mixinMethod(); + +class DerivedFromAbstract extends Mixin(AbstractBase) { + abstractBaseMethod() {} +} + +const wasAbstract = new DerivedFromAbstract(); +wasAbstract.abstractBaseMethod(); +wasAbstract.mixinMethod(); + +//// [mixinAbstractClasses.js] +function Mixin(baseClass) { + class MixinClass extends baseClass { + mixinMethod() { + } + } + return MixinClass; +} +class ConcreteBase { + baseMethod() { } +} +class AbstractBase { +} +class DerivedFromConcrete extends Mixin(ConcreteBase) { +} +const wasConcrete = new DerivedFromConcrete(); +wasConcrete.baseMethod(); +wasConcrete.mixinMethod(); +class DerivedFromAbstract extends Mixin(AbstractBase) { + abstractBaseMethod() { } +} +const wasAbstract = new DerivedFromAbstract(); +wasAbstract.abstractBaseMethod(); +wasAbstract.mixinMethod(); + + +//// [mixinAbstractClasses.d.ts] +interface Mixin { + mixinMethod(): void; +} +declare function Mixin any>(baseClass: TBaseClass): TBaseClass & (abstract new (...args: any) => Mixin); +declare class ConcreteBase { + baseMethod(): void; +} +declare abstract class AbstractBase { + abstract abstractBaseMethod(): void; +} +declare const DerivedFromConcrete_base: typeof ConcreteBase & (abstract new (...args: any) => Mixin); +declare class DerivedFromConcrete extends DerivedFromConcrete_base { +} +declare const wasConcrete: DerivedFromConcrete; +declare const DerivedFromAbstract_base: typeof AbstractBase & (abstract new (...args: any) => Mixin); +declare class DerivedFromAbstract extends DerivedFromAbstract_base { + abstractBaseMethod(): void; +} +declare const wasAbstract: DerivedFromAbstract; diff --git a/tests/baselines/reference/mixinAbstractClasses.symbols b/tests/baselines/reference/mixinAbstractClasses.symbols new file mode 100644 index 0000000000000..1c45de5e900ff --- /dev/null +++ b/tests/baselines/reference/mixinAbstractClasses.symbols @@ -0,0 +1,88 @@ +=== tests/cases/conformance/classes/mixinAbstractClasses.ts === +interface Mixin { +>Mixin : Symbol(Mixin, Decl(mixinAbstractClasses.ts, 2, 1), Decl(mixinAbstractClasses.ts, 0, 0)) + + mixinMethod(): void; +>mixinMethod : Symbol(Mixin.mixinMethod, Decl(mixinAbstractClasses.ts, 0, 17)) +} + +function Mixin any>(baseClass: TBaseClass): TBaseClass & (abstract new (...args: any) => Mixin) { +>Mixin : Symbol(Mixin, Decl(mixinAbstractClasses.ts, 2, 1), Decl(mixinAbstractClasses.ts, 0, 0)) +>TBaseClass : Symbol(TBaseClass, Decl(mixinAbstractClasses.ts, 4, 15)) +>args : Symbol(args, Decl(mixinAbstractClasses.ts, 4, 48)) +>baseClass : Symbol(baseClass, Decl(mixinAbstractClasses.ts, 4, 70)) +>TBaseClass : Symbol(TBaseClass, Decl(mixinAbstractClasses.ts, 4, 15)) +>TBaseClass : Symbol(TBaseClass, Decl(mixinAbstractClasses.ts, 4, 15)) +>args : Symbol(args, Decl(mixinAbstractClasses.ts, 4, 122)) +>Mixin : Symbol(Mixin, Decl(mixinAbstractClasses.ts, 2, 1), Decl(mixinAbstractClasses.ts, 0, 0)) + + abstract class MixinClass extends baseClass implements Mixin { +>MixinClass : Symbol(MixinClass, Decl(mixinAbstractClasses.ts, 4, 147)) +>baseClass : Symbol(baseClass, Decl(mixinAbstractClasses.ts, 4, 70)) +>Mixin : Symbol(Mixin, Decl(mixinAbstractClasses.ts, 2, 1), Decl(mixinAbstractClasses.ts, 0, 0)) + + mixinMethod() { +>mixinMethod : Symbol(MixinClass.mixinMethod, Decl(mixinAbstractClasses.ts, 5, 66)) + } + } + return MixinClass; +>MixinClass : Symbol(MixinClass, Decl(mixinAbstractClasses.ts, 4, 147)) +} + +class ConcreteBase { +>ConcreteBase : Symbol(ConcreteBase, Decl(mixinAbstractClasses.ts, 10, 1)) + + baseMethod() {} +>baseMethod : Symbol(ConcreteBase.baseMethod, Decl(mixinAbstractClasses.ts, 12, 20)) +} + +abstract class AbstractBase { +>AbstractBase : Symbol(AbstractBase, Decl(mixinAbstractClasses.ts, 14, 1)) + + abstract abstractBaseMethod(): void; +>abstractBaseMethod : Symbol(AbstractBase.abstractBaseMethod, Decl(mixinAbstractClasses.ts, 16, 29)) +} + +class DerivedFromConcrete extends Mixin(ConcreteBase) { +>DerivedFromConcrete : Symbol(DerivedFromConcrete, Decl(mixinAbstractClasses.ts, 18, 1)) +>Mixin : Symbol(Mixin, Decl(mixinAbstractClasses.ts, 2, 1), Decl(mixinAbstractClasses.ts, 0, 0)) +>ConcreteBase : Symbol(ConcreteBase, Decl(mixinAbstractClasses.ts, 10, 1)) +} + +const wasConcrete = new DerivedFromConcrete(); +>wasConcrete : Symbol(wasConcrete, Decl(mixinAbstractClasses.ts, 23, 5)) +>DerivedFromConcrete : Symbol(DerivedFromConcrete, Decl(mixinAbstractClasses.ts, 18, 1)) + +wasConcrete.baseMethod(); +>wasConcrete.baseMethod : Symbol(ConcreteBase.baseMethod, Decl(mixinAbstractClasses.ts, 12, 20)) +>wasConcrete : Symbol(wasConcrete, Decl(mixinAbstractClasses.ts, 23, 5)) +>baseMethod : Symbol(ConcreteBase.baseMethod, Decl(mixinAbstractClasses.ts, 12, 20)) + +wasConcrete.mixinMethod(); +>wasConcrete.mixinMethod : Symbol(Mixin.mixinMethod, Decl(mixinAbstractClasses.ts, 0, 17)) +>wasConcrete : Symbol(wasConcrete, Decl(mixinAbstractClasses.ts, 23, 5)) +>mixinMethod : Symbol(Mixin.mixinMethod, Decl(mixinAbstractClasses.ts, 0, 17)) + +class DerivedFromAbstract extends Mixin(AbstractBase) { +>DerivedFromAbstract : Symbol(DerivedFromAbstract, Decl(mixinAbstractClasses.ts, 25, 26)) +>Mixin : Symbol(Mixin, Decl(mixinAbstractClasses.ts, 2, 1), Decl(mixinAbstractClasses.ts, 0, 0)) +>AbstractBase : Symbol(AbstractBase, Decl(mixinAbstractClasses.ts, 14, 1)) + + abstractBaseMethod() {} +>abstractBaseMethod : Symbol(DerivedFromAbstract.abstractBaseMethod, Decl(mixinAbstractClasses.ts, 27, 55)) +} + +const wasAbstract = new DerivedFromAbstract(); +>wasAbstract : Symbol(wasAbstract, Decl(mixinAbstractClasses.ts, 31, 5)) +>DerivedFromAbstract : Symbol(DerivedFromAbstract, Decl(mixinAbstractClasses.ts, 25, 26)) + +wasAbstract.abstractBaseMethod(); +>wasAbstract.abstractBaseMethod : Symbol(DerivedFromAbstract.abstractBaseMethod, Decl(mixinAbstractClasses.ts, 27, 55)) +>wasAbstract : Symbol(wasAbstract, Decl(mixinAbstractClasses.ts, 31, 5)) +>abstractBaseMethod : Symbol(DerivedFromAbstract.abstractBaseMethod, Decl(mixinAbstractClasses.ts, 27, 55)) + +wasAbstract.mixinMethod(); +>wasAbstract.mixinMethod : Symbol(Mixin.mixinMethod, Decl(mixinAbstractClasses.ts, 0, 17)) +>wasAbstract : Symbol(wasAbstract, Decl(mixinAbstractClasses.ts, 31, 5)) +>mixinMethod : Symbol(Mixin.mixinMethod, Decl(mixinAbstractClasses.ts, 0, 17)) + diff --git a/tests/baselines/reference/mixinAbstractClasses.types b/tests/baselines/reference/mixinAbstractClasses.types new file mode 100644 index 0000000000000..aba29eb94c241 --- /dev/null +++ b/tests/baselines/reference/mixinAbstractClasses.types @@ -0,0 +1,89 @@ +=== tests/cases/conformance/classes/mixinAbstractClasses.ts === +interface Mixin { + mixinMethod(): void; +>mixinMethod : () => void +} + +function Mixin any>(baseClass: TBaseClass): TBaseClass & (abstract new (...args: any) => Mixin) { +>Mixin : any>(baseClass: TBaseClass) => TBaseClass & (abstract new (...args: any) => Mixin) +>args : any +>baseClass : TBaseClass +>args : any + + abstract class MixinClass extends baseClass implements Mixin { +>MixinClass : MixinClass +>baseClass : TBaseClass + + mixinMethod() { +>mixinMethod : () => void + } + } + return MixinClass; +>MixinClass : ((abstract new (...args: any) => MixinClass) & { prototype: Mixin.MixinClass; }) & TBaseClass +} + +class ConcreteBase { +>ConcreteBase : ConcreteBase + + baseMethod() {} +>baseMethod : () => void +} + +abstract class AbstractBase { +>AbstractBase : AbstractBase + + abstract abstractBaseMethod(): void; +>abstractBaseMethod : () => void +} + +class DerivedFromConcrete extends Mixin(ConcreteBase) { +>DerivedFromConcrete : DerivedFromConcrete +>Mixin(ConcreteBase) : ConcreteBase & Mixin +>Mixin : any>(baseClass: TBaseClass) => TBaseClass & (abstract new (...args: any) => Mixin) +>ConcreteBase : typeof ConcreteBase +} + +const wasConcrete = new DerivedFromConcrete(); +>wasConcrete : DerivedFromConcrete +>new DerivedFromConcrete() : DerivedFromConcrete +>DerivedFromConcrete : typeof DerivedFromConcrete + +wasConcrete.baseMethod(); +>wasConcrete.baseMethod() : void +>wasConcrete.baseMethod : () => void +>wasConcrete : DerivedFromConcrete +>baseMethod : () => void + +wasConcrete.mixinMethod(); +>wasConcrete.mixinMethod() : void +>wasConcrete.mixinMethod : () => void +>wasConcrete : DerivedFromConcrete +>mixinMethod : () => void + +class DerivedFromAbstract extends Mixin(AbstractBase) { +>DerivedFromAbstract : DerivedFromAbstract +>Mixin(AbstractBase) : AbstractBase & Mixin +>Mixin : any>(baseClass: TBaseClass) => TBaseClass & (abstract new (...args: any) => Mixin) +>AbstractBase : typeof AbstractBase + + abstractBaseMethod() {} +>abstractBaseMethod : () => void +} + +const wasAbstract = new DerivedFromAbstract(); +>wasAbstract : DerivedFromAbstract +>new DerivedFromAbstract() : DerivedFromAbstract +>DerivedFromAbstract : typeof DerivedFromAbstract + +wasAbstract.abstractBaseMethod(); +>wasAbstract.abstractBaseMethod() : void +>wasAbstract.abstractBaseMethod : () => void +>wasAbstract : DerivedFromAbstract +>abstractBaseMethod : () => void + +wasAbstract.mixinMethod(); +>wasAbstract.mixinMethod() : void +>wasAbstract.mixinMethod : () => void +>wasAbstract : DerivedFromAbstract +>mixinMethod : () => void + diff --git a/tests/baselines/reference/mixinAbstractClassesReturnTypeInference.js b/tests/baselines/reference/mixinAbstractClassesReturnTypeInference.js new file mode 100644 index 0000000000000..afdbfdf995f73 --- /dev/null +++ b/tests/baselines/reference/mixinAbstractClassesReturnTypeInference.js @@ -0,0 +1,63 @@ +//// [mixinAbstractClassesReturnTypeInference.ts] +interface Mixin1 { + mixinMethod(): void; +} + +abstract class AbstractBase { + abstract abstractBaseMethod(): void; +} + +function Mixin2 any>(baseClass: TBase) { + // must be `abstract` because we cannot know *all* of the possible abstract members that need to be + // implemented for this to be concrete. + abstract class MixinClass extends baseClass implements Mixin1 { + mixinMethod(): void {} + static staticMixinMethod(): void {} + } + return MixinClass; +} + +class DerivedFromAbstract2 extends Mixin2(AbstractBase) { + abstractBaseMethod() {} +} + + +//// [mixinAbstractClassesReturnTypeInference.js] +class AbstractBase { +} +function Mixin2(baseClass) { + // must be `abstract` because we cannot know *all* of the possible abstract members that need to be + // implemented for this to be concrete. + class MixinClass extends baseClass { + mixinMethod() { } + static staticMixinMethod() { } + } + return MixinClass; +} +class DerivedFromAbstract2 extends Mixin2(AbstractBase) { + abstractBaseMethod() { } +} + + +//// [mixinAbstractClassesReturnTypeInference.d.ts] +interface Mixin1 { + mixinMethod(): void; +} +declare abstract class AbstractBase { + abstract abstractBaseMethod(): void; +} +declare function Mixin2 any>(baseClass: TBase): ((abstract new (...args: any[]) => { + [x: string]: any; + mixinMethod(): void; +}) & { + staticMixinMethod(): void; +}) & TBase; +declare const DerivedFromAbstract2_base: ((abstract new (...args: any[]) => { + [x: string]: any; + mixinMethod(): void; +}) & { + staticMixinMethod(): void; +}) & typeof AbstractBase; +declare class DerivedFromAbstract2 extends DerivedFromAbstract2_base { + abstractBaseMethod(): void; +} diff --git a/tests/baselines/reference/mixinAbstractClassesReturnTypeInference.symbols b/tests/baselines/reference/mixinAbstractClassesReturnTypeInference.symbols new file mode 100644 index 0000000000000..bf435467ed7ac --- /dev/null +++ b/tests/baselines/reference/mixinAbstractClassesReturnTypeInference.symbols @@ -0,0 +1,48 @@ +=== tests/cases/conformance/classes/mixinAbstractClassesReturnTypeInference.ts === +interface Mixin1 { +>Mixin1 : Symbol(Mixin1, Decl(mixinAbstractClassesReturnTypeInference.ts, 0, 0)) + + mixinMethod(): void; +>mixinMethod : Symbol(Mixin1.mixinMethod, Decl(mixinAbstractClassesReturnTypeInference.ts, 0, 18)) +} + +abstract class AbstractBase { +>AbstractBase : Symbol(AbstractBase, Decl(mixinAbstractClassesReturnTypeInference.ts, 2, 1)) + + abstract abstractBaseMethod(): void; +>abstractBaseMethod : Symbol(AbstractBase.abstractBaseMethod, Decl(mixinAbstractClassesReturnTypeInference.ts, 4, 29)) +} + +function Mixin2 any>(baseClass: TBase) { +>Mixin2 : Symbol(Mixin2, Decl(mixinAbstractClassesReturnTypeInference.ts, 6, 1)) +>TBase : Symbol(TBase, Decl(mixinAbstractClassesReturnTypeInference.ts, 8, 16)) +>args : Symbol(args, Decl(mixinAbstractClassesReturnTypeInference.ts, 8, 44)) +>baseClass : Symbol(baseClass, Decl(mixinAbstractClassesReturnTypeInference.ts, 8, 68)) +>TBase : Symbol(TBase, Decl(mixinAbstractClassesReturnTypeInference.ts, 8, 16)) + + // must be `abstract` because we cannot know *all* of the possible abstract members that need to be + // implemented for this to be concrete. + abstract class MixinClass extends baseClass implements Mixin1 { +>MixinClass : Symbol(MixinClass, Decl(mixinAbstractClassesReturnTypeInference.ts, 8, 87)) +>baseClass : Symbol(baseClass, Decl(mixinAbstractClassesReturnTypeInference.ts, 8, 68)) +>Mixin1 : Symbol(Mixin1, Decl(mixinAbstractClassesReturnTypeInference.ts, 0, 0)) + + mixinMethod(): void {} +>mixinMethod : Symbol(MixinClass.mixinMethod, Decl(mixinAbstractClassesReturnTypeInference.ts, 11, 67)) + + static staticMixinMethod(): void {} +>staticMixinMethod : Symbol(MixinClass.staticMixinMethod, Decl(mixinAbstractClassesReturnTypeInference.ts, 12, 30)) + } + return MixinClass; +>MixinClass : Symbol(MixinClass, Decl(mixinAbstractClassesReturnTypeInference.ts, 8, 87)) +} + +class DerivedFromAbstract2 extends Mixin2(AbstractBase) { +>DerivedFromAbstract2 : Symbol(DerivedFromAbstract2, Decl(mixinAbstractClassesReturnTypeInference.ts, 16, 1)) +>Mixin2 : Symbol(Mixin2, Decl(mixinAbstractClassesReturnTypeInference.ts, 6, 1)) +>AbstractBase : Symbol(AbstractBase, Decl(mixinAbstractClassesReturnTypeInference.ts, 2, 1)) + + abstractBaseMethod() {} +>abstractBaseMethod : Symbol(DerivedFromAbstract2.abstractBaseMethod, Decl(mixinAbstractClassesReturnTypeInference.ts, 18, 57)) +} + diff --git a/tests/baselines/reference/mixinAbstractClassesReturnTypeInference.types b/tests/baselines/reference/mixinAbstractClassesReturnTypeInference.types new file mode 100644 index 0000000000000..460d4c6891952 --- /dev/null +++ b/tests/baselines/reference/mixinAbstractClassesReturnTypeInference.types @@ -0,0 +1,44 @@ +=== tests/cases/conformance/classes/mixinAbstractClassesReturnTypeInference.ts === +interface Mixin1 { + mixinMethod(): void; +>mixinMethod : () => void +} + +abstract class AbstractBase { +>AbstractBase : AbstractBase + + abstract abstractBaseMethod(): void; +>abstractBaseMethod : () => void +} + +function Mixin2 any>(baseClass: TBase) { +>Mixin2 : any>(baseClass: TBase) => ((abstract new (...args: any[]) => MixinClass) & { prototype: Mixin2.MixinClass; staticMixinMethod(): void; }) & TBase +>args : any[] +>baseClass : TBase + + // must be `abstract` because we cannot know *all* of the possible abstract members that need to be + // implemented for this to be concrete. + abstract class MixinClass extends baseClass implements Mixin1 { +>MixinClass : MixinClass +>baseClass : TBase + + mixinMethod(): void {} +>mixinMethod : () => void + + static staticMixinMethod(): void {} +>staticMixinMethod : () => void + } + return MixinClass; +>MixinClass : ((abstract new (...args: any[]) => MixinClass) & { prototype: Mixin2.MixinClass; staticMixinMethod(): void; }) & TBase +} + +class DerivedFromAbstract2 extends Mixin2(AbstractBase) { +>DerivedFromAbstract2 : DerivedFromAbstract2 +>Mixin2(AbstractBase) : Mixin2.MixinClass & AbstractBase +>Mixin2 : any>(baseClass: TBase) => ((abstract new (...args: any[]) => MixinClass) & { prototype: Mixin2.MixinClass; staticMixinMethod(): void; }) & TBase +>AbstractBase : typeof AbstractBase + + abstractBaseMethod() {} +>abstractBaseMethod : () => void +} + diff --git a/tests/baselines/reference/unionTypeConstructSignatures.errors.txt b/tests/baselines/reference/unionTypeConstructSignatures.errors.txt index 6ae542f0f2ff6..1ab3c94458146 100644 --- a/tests/baselines/reference/unionTypeConstructSignatures.errors.txt +++ b/tests/baselines/reference/unionTypeConstructSignatures.errors.txt @@ -34,18 +34,19 @@ tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(62,49): erro tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(63,12): error TS2554: Expected 2 arguments, but got 0. tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(69,49): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(70,12): error TS2555: Expected at least 1 arguments, but got 0. +tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(73,1): error TS2511: Cannot create an instance of an abstract class. -==== tests/cases/conformance/types/union/unionTypeConstructSignatures.ts (27 errors) ==== +==== tests/cases/conformance/types/union/unionTypeConstructSignatures.ts (28 errors) ==== var numOrDate: number | Date; var strOrBoolean: string | boolean; var strOrNum: string | number; - // If each type in U has construct signatures and the sets of construct signatures are identical ignoring return types, + // If each type in U has construct signatures and the sets of construct signatures are identical ignoring return types, // U has the same set of construct signatures, but with return types that are unions of the return types of the respective construct signatures from each type in U. var unionOfDifferentReturnType: { new (a: number): number; } | { new (a: number): Date; }; numOrDate = new unionOfDifferentReturnType(10); - strOrBoolean = new unionOfDifferentReturnType("hello"); // error + strOrBoolean = new unionOfDifferentReturnType("hello"); // error ~~~~~~~~~~~~ !!! error TS2322: Type 'number | Date' is not assignable to type 'string | boolean'. !!! error TS2322: Type 'number' is not assignable to type 'string | boolean'. @@ -182,4 +183,10 @@ tests/cases/conformance/types/union/unionTypeConstructSignatures.ts(70,12): erro strOrNum = new unionWithRestParameter3(); // error no call signature ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2555: Expected at least 1 arguments, but got 0. -!!! related TS6210 tests/cases/conformance/types/union/unionTypeConstructSignatures.ts:65:37: An argument for 'a' was not provided. \ No newline at end of file +!!! related TS6210 tests/cases/conformance/types/union/unionTypeConstructSignatures.ts:65:37: An argument for 'a' was not provided. + + var unionWithAbstractSignature: (abstract new (a: string) => string) | (new (a: string) => string); + new unionWithAbstractSignature('hello'); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2511: Cannot create an instance of an abstract class. + \ No newline at end of file diff --git a/tests/baselines/reference/unionTypeConstructSignatures.js b/tests/baselines/reference/unionTypeConstructSignatures.js index 668ad3f335da9..2f5bb59d305e1 100644 --- a/tests/baselines/reference/unionTypeConstructSignatures.js +++ b/tests/baselines/reference/unionTypeConstructSignatures.js @@ -3,11 +3,11 @@ var numOrDate: number | Date; var strOrBoolean: string | boolean; var strOrNum: string | number; -// If each type in U has construct signatures and the sets of construct signatures are identical ignoring return types, +// If each type in U has construct signatures and the sets of construct signatures are identical ignoring return types, // U has the same set of construct signatures, but with return types that are unions of the return types of the respective construct signatures from each type in U. var unionOfDifferentReturnType: { new (a: number): number; } | { new (a: number): Date; }; numOrDate = new unionOfDifferentReturnType(10); -strOrBoolean = new unionOfDifferentReturnType("hello"); // error +strOrBoolean = new unionOfDifferentReturnType("hello"); // error new unionOfDifferentReturnType1(true); // error in type of parameter var unionOfDifferentReturnType1: { new (a: number): number; new (a: string): string; } | { new (a: number): Date; new (a: string): boolean; }; @@ -68,17 +68,21 @@ strOrNum = new unionWithRestParameter3('hello'); // error no call signature strOrNum = new unionWithRestParameter3('hello', 10); // ok strOrNum = new unionWithRestParameter3('hello', 10, 11); // ok strOrNum = new unionWithRestParameter3('hello', "hello"); // wrong type -strOrNum = new unionWithRestParameter3(); // error no call signature +strOrNum = new unionWithRestParameter3(); // error no call signature + +var unionWithAbstractSignature: (abstract new (a: string) => string) | (new (a: string) => string); +new unionWithAbstractSignature('hello'); + //// [unionTypeConstructSignatures.js] var numOrDate; var strOrBoolean; var strOrNum; -// If each type in U has construct signatures and the sets of construct signatures are identical ignoring return types, +// If each type in U has construct signatures and the sets of construct signatures are identical ignoring return types, // U has the same set of construct signatures, but with return types that are unions of the return types of the respective construct signatures from each type in U. var unionOfDifferentReturnType; numOrDate = new unionOfDifferentReturnType(10); -strOrBoolean = new unionOfDifferentReturnType("hello"); // error +strOrBoolean = new unionOfDifferentReturnType("hello"); // error new unionOfDifferentReturnType1(true); // error in type of parameter var unionOfDifferentReturnType1; numOrDate = new unionOfDifferentReturnType1(10); @@ -130,3 +134,5 @@ strOrNum = new unionWithRestParameter3('hello', 10); // ok strOrNum = new unionWithRestParameter3('hello', 10, 11); // ok strOrNum = new unionWithRestParameter3('hello', "hello"); // wrong type strOrNum = new unionWithRestParameter3(); // error no call signature +var unionWithAbstractSignature; +new unionWithAbstractSignature('hello'); diff --git a/tests/baselines/reference/unionTypeConstructSignatures.symbols b/tests/baselines/reference/unionTypeConstructSignatures.symbols index ce4cc97bc1b51..797a6e73ebe92 100644 --- a/tests/baselines/reference/unionTypeConstructSignatures.symbols +++ b/tests/baselines/reference/unionTypeConstructSignatures.symbols @@ -9,7 +9,7 @@ var strOrBoolean: string | boolean; var strOrNum: string | number; >strOrNum : Symbol(strOrNum, Decl(unionTypeConstructSignatures.ts, 2, 3)) -// If each type in U has construct signatures and the sets of construct signatures are identical ignoring return types, +// If each type in U has construct signatures and the sets of construct signatures are identical ignoring return types, // U has the same set of construct signatures, but with return types that are unions of the return types of the respective construct signatures from each type in U. var unionOfDifferentReturnType: { new (a: number): number; } | { new (a: number): Date; }; >unionOfDifferentReturnType : Symbol(unionOfDifferentReturnType, Decl(unionTypeConstructSignatures.ts, 6, 3)) @@ -21,7 +21,7 @@ numOrDate = new unionOfDifferentReturnType(10); >numOrDate : Symbol(numOrDate, Decl(unionTypeConstructSignatures.ts, 0, 3)) >unionOfDifferentReturnType : Symbol(unionOfDifferentReturnType, Decl(unionTypeConstructSignatures.ts, 6, 3)) -strOrBoolean = new unionOfDifferentReturnType("hello"); // error +strOrBoolean = new unionOfDifferentReturnType("hello"); // error >strOrBoolean : Symbol(strOrBoolean, Decl(unionTypeConstructSignatures.ts, 1, 3)) >unionOfDifferentReturnType : Symbol(unionOfDifferentReturnType, Decl(unionTypeConstructSignatures.ts, 6, 3)) @@ -244,3 +244,11 @@ strOrNum = new unionWithRestParameter3(); // error no call signature >strOrNum : Symbol(strOrNum, Decl(unionTypeConstructSignatures.ts, 2, 3)) >unionWithRestParameter3 : Symbol(unionWithRestParameter3, Decl(unionTypeConstructSignatures.ts, 64, 3)) +var unionWithAbstractSignature: (abstract new (a: string) => string) | (new (a: string) => string); +>unionWithAbstractSignature : Symbol(unionWithAbstractSignature, Decl(unionTypeConstructSignatures.ts, 71, 3)) +>a : Symbol(a, Decl(unionTypeConstructSignatures.ts, 71, 47)) +>a : Symbol(a, Decl(unionTypeConstructSignatures.ts, 71, 77)) + +new unionWithAbstractSignature('hello'); +>unionWithAbstractSignature : Symbol(unionWithAbstractSignature, Decl(unionTypeConstructSignatures.ts, 71, 3)) + diff --git a/tests/baselines/reference/unionTypeConstructSignatures.types b/tests/baselines/reference/unionTypeConstructSignatures.types index 27e1797588783..70171c4248ed5 100644 --- a/tests/baselines/reference/unionTypeConstructSignatures.types +++ b/tests/baselines/reference/unionTypeConstructSignatures.types @@ -8,7 +8,7 @@ var strOrBoolean: string | boolean; var strOrNum: string | number; >strOrNum : string | number -// If each type in U has construct signatures and the sets of construct signatures are identical ignoring return types, +// If each type in U has construct signatures and the sets of construct signatures are identical ignoring return types, // U has the same set of construct signatures, but with return types that are unions of the return types of the respective construct signatures from each type in U. var unionOfDifferentReturnType: { new (a: number): number; } | { new (a: number): Date; }; >unionOfDifferentReturnType : (new (a: number) => number) | (new (a: number) => Date) @@ -22,7 +22,7 @@ numOrDate = new unionOfDifferentReturnType(10); >unionOfDifferentReturnType : (new (a: number) => number) | (new (a: number) => Date) >10 : 10 -strOrBoolean = new unionOfDifferentReturnType("hello"); // error +strOrBoolean = new unionOfDifferentReturnType("hello"); // error >strOrBoolean = new unionOfDifferentReturnType("hello") : number | Date >strOrBoolean : string | boolean >new unionOfDifferentReturnType("hello") : number | Date @@ -365,3 +365,13 @@ strOrNum = new unionWithRestParameter3(); // error no call signature >new unionWithRestParameter3() : string | number >unionWithRestParameter3 : (new (a: string, ...b: number[]) => string) | (new (a: string) => number) +var unionWithAbstractSignature: (abstract new (a: string) => string) | (new (a: string) => string); +>unionWithAbstractSignature : (abstract new (a: string) => string) | (new (a: string) => string) +>a : string +>a : string + +new unionWithAbstractSignature('hello'); +>new unionWithAbstractSignature('hello') : any +>unionWithAbstractSignature : (abstract new (a: string) => string) | (new (a: string) => string) +>'hello' : "hello" + diff --git a/tests/cases/conformance/classes/mixinAbstractClasses.2.ts b/tests/cases/conformance/classes/mixinAbstractClasses.2.ts new file mode 100644 index 0000000000000..1c4798e076d10 --- /dev/null +++ b/tests/cases/conformance/classes/mixinAbstractClasses.2.ts @@ -0,0 +1,28 @@ +// @target: esnext +// @declaration: true + +interface Mixin { + mixinMethod(): void; +} + +function Mixin any>(baseClass: TBaseClass): TBaseClass & (abstract new (...args: any) => Mixin) { + // error expected: A mixin class that extends from a type variable containing an abstract construct signature must also be declared 'abstract'. + class MixinClass extends baseClass implements Mixin { + mixinMethod() { + } + } + return MixinClass; +} + +abstract class AbstractBase { + abstract abstractBaseMethod(): void; +} + +const MixedBase = Mixin(AbstractBase); + +// error expected: Non-abstract class 'DerivedFromAbstract' does not implement inherited abstract member 'abstractBaseMethod' from class 'AbstractBase & Mixin'. +class DerivedFromAbstract extends MixedBase { +} + +// error expected: Cannot create an instance of an abstract class. +new MixedBase(); \ No newline at end of file diff --git a/tests/cases/conformance/classes/mixinAbstractClasses.ts b/tests/cases/conformance/classes/mixinAbstractClasses.ts new file mode 100644 index 0000000000000..5bfad6b769a3e --- /dev/null +++ b/tests/cases/conformance/classes/mixinAbstractClasses.ts @@ -0,0 +1,37 @@ +// @target: esnext +// @declaration: true + +interface Mixin { + mixinMethod(): void; +} + +function Mixin any>(baseClass: TBaseClass): TBaseClass & (abstract new (...args: any) => Mixin) { + abstract class MixinClass extends baseClass implements Mixin { + mixinMethod() { + } + } + return MixinClass; +} + +class ConcreteBase { + baseMethod() {} +} + +abstract class AbstractBase { + abstract abstractBaseMethod(): void; +} + +class DerivedFromConcrete extends Mixin(ConcreteBase) { +} + +const wasConcrete = new DerivedFromConcrete(); +wasConcrete.baseMethod(); +wasConcrete.mixinMethod(); + +class DerivedFromAbstract extends Mixin(AbstractBase) { + abstractBaseMethod() {} +} + +const wasAbstract = new DerivedFromAbstract(); +wasAbstract.abstractBaseMethod(); +wasAbstract.mixinMethod(); \ No newline at end of file diff --git a/tests/cases/conformance/classes/mixinAbstractClassesReturnTypeInference.ts b/tests/cases/conformance/classes/mixinAbstractClassesReturnTypeInference.ts new file mode 100644 index 0000000000000..3adf08a6b6e51 --- /dev/null +++ b/tests/cases/conformance/classes/mixinAbstractClassesReturnTypeInference.ts @@ -0,0 +1,24 @@ +// @target: esnext +// @declaration: true + +interface Mixin1 { + mixinMethod(): void; +} + +abstract class AbstractBase { + abstract abstractBaseMethod(): void; +} + +function Mixin2 any>(baseClass: TBase) { + // must be `abstract` because we cannot know *all* of the possible abstract members that need to be + // implemented for this to be concrete. + abstract class MixinClass extends baseClass implements Mixin1 { + mixinMethod(): void {} + static staticMixinMethod(): void {} + } + return MixinClass; +} + +class DerivedFromAbstract2 extends Mixin2(AbstractBase) { + abstractBaseMethod() {} +} diff --git a/tests/cases/conformance/types/conditional/inferTypes1.ts b/tests/cases/conformance/types/conditional/inferTypes1.ts index 3be629b86ba88..afcb58aff5d64 100644 --- a/tests/cases/conformance/types/conditional/inferTypes1.ts +++ b/tests/cases/conformance/types/conditional/inferTypes1.ts @@ -24,6 +24,11 @@ class C { y = 0; } +abstract class Abstract { + x = 0; + y = 0; +} + type T10 = ReturnType<() => string>; // string type T11 = ReturnType<(s: string) => void>; // void type T12 = ReturnType<(() => T)>; // {} @@ -40,6 +45,9 @@ type U11 = InstanceType; // any type U12 = InstanceType; // never type U13 = InstanceType; // Error type U14 = InstanceType; // Error +type U15 = InstanceType; // Abstract +type U16 = InstanceType T[]>; // T[] +type U17 = InstanceType T[]>; // T[] type ArgumentType any> = T extends (a: infer A) => any ? A : any; diff --git a/tests/cases/conformance/types/union/unionTypeConstructSignatures.ts b/tests/cases/conformance/types/union/unionTypeConstructSignatures.ts index 8f38e38aee062..3e0d509fe97f3 100644 --- a/tests/cases/conformance/types/union/unionTypeConstructSignatures.ts +++ b/tests/cases/conformance/types/union/unionTypeConstructSignatures.ts @@ -2,11 +2,11 @@ var strOrBoolean: string | boolean; var strOrNum: string | number; -// If each type in U has construct signatures and the sets of construct signatures are identical ignoring return types, +// If each type in U has construct signatures and the sets of construct signatures are identical ignoring return types, // U has the same set of construct signatures, but with return types that are unions of the return types of the respective construct signatures from each type in U. var unionOfDifferentReturnType: { new (a: number): number; } | { new (a: number): Date; }; numOrDate = new unionOfDifferentReturnType(10); -strOrBoolean = new unionOfDifferentReturnType("hello"); // error +strOrBoolean = new unionOfDifferentReturnType("hello"); // error new unionOfDifferentReturnType1(true); // error in type of parameter var unionOfDifferentReturnType1: { new (a: number): number; new (a: string): string; } | { new (a: number): Date; new (a: string): boolean; }; @@ -67,4 +67,7 @@ strOrNum = new unionWithRestParameter3('hello'); // error no call signature strOrNum = new unionWithRestParameter3('hello', 10); // ok strOrNum = new unionWithRestParameter3('hello', 10, 11); // ok strOrNum = new unionWithRestParameter3('hello', "hello"); // wrong type -strOrNum = new unionWithRestParameter3(); // error no call signature \ No newline at end of file +strOrNum = new unionWithRestParameter3(); // error no call signature + +var unionWithAbstractSignature: (abstract new (a: string) => string) | (new (a: string) => string); +new unionWithAbstractSignature('hello');