From 3d3dae089f79c2839fc9a7133c1c00fd0fc83aa3 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Fri, 13 Jan 2017 22:53:02 -0800 Subject: [PATCH] Adds support for type parameter defaults --- src/compiler/checker.ts | 265 ++++++++-- src/compiler/declarationEmitter.ts | 17 + src/compiler/diagnosticMessages.json | 12 + src/compiler/parser.ts | 5 + src/compiler/types.ts | 11 + src/services/services.ts | 1 + tests/baselines/reference/genericDefaults.js | 238 +++++++++ .../reference/genericDefaults.symbols | 390 ++++++++++++++ .../baselines/reference/genericDefaults.types | 500 ++++++++++++++++++ .../genericDefaultsErrors.errors.txt | 114 ++++ .../reference/genericDefaultsErrors.js | 87 +++ tests/cases/compiler/genericDefaults.ts | 86 +++ tests/cases/compiler/genericDefaultsErrors.ts | 39 ++ 13 files changed, 1711 insertions(+), 54 deletions(-) create mode 100644 tests/baselines/reference/genericDefaults.js create mode 100644 tests/baselines/reference/genericDefaults.symbols create mode 100644 tests/baselines/reference/genericDefaults.types create mode 100644 tests/baselines/reference/genericDefaultsErrors.errors.txt create mode 100644 tests/baselines/reference/genericDefaultsErrors.js create mode 100644 tests/cases/compiler/genericDefaults.ts create mode 100644 tests/cases/compiler/genericDefaultsErrors.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9e4e81e3da9..96ee4835b9c 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -164,13 +164,13 @@ namespace ts { // in getPropagatingFlagsOfTypes, and it is checked in inferFromTypes. anyFunctionType.flags |= TypeFlags.ContainsAnyFunctionType; - const noConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); - const circularConstraintType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); + const noConstraintOrDefaultType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); + const circularConstraintOrDefaultType = createAnonymousType(undefined, emptySymbols, emptyArray, emptyArray, undefined, undefined); - const anySignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); - const unknownSignature = createSignature(undefined, undefined, undefined, emptyArray, unknownType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); - const resolvingSignature = createSignature(undefined, undefined, undefined, emptyArray, anyType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); - const silentNeverSignature = createSignature(undefined, undefined, undefined, emptyArray, silentNeverType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); + const anySignature = createSignature(undefined, undefined, 0, undefined, emptyArray, anyType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); + const unknownSignature = createSignature(undefined, undefined, 0, undefined, emptyArray, unknownType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); + const resolvingSignature = createSignature(undefined, undefined, 0, undefined, emptyArray, anyType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); + const silentNeverSignature = createSignature(undefined, undefined, 0, undefined, emptyArray, silentNeverType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false); const enumNumberIndexInfo = createIndexInfo(stringType, /*isReadonly*/ true); @@ -374,7 +374,8 @@ namespace ts { Type, ResolvedBaseConstructorType, DeclaredType, - ResolvedReturnType + ResolvedReturnType, + ResolvedDefault } const builtinGlobals = createMap(); @@ -2650,6 +2651,13 @@ namespace ts { writeSpace(writer); buildTypeDisplay(constraint, writer, enclosingDeclaration, flags, symbolStack); } + const defaultType = getDefaultOfTypeParameter(tp); + if (defaultType) { + writeSpace(writer); + writePunctuation(writer, SyntaxKind.EqualsToken); + writeSpace(writer); + buildTypeDisplay(defaultType, writer, enclosingDeclaration, flags, symbolStack); + } } function buildParameterDisplay(p: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, symbolStack?: Symbol[]) { @@ -3046,6 +3054,9 @@ namespace ts { if (propertyName === TypeSystemPropertyName.ResolvedReturnType) { return (target).resolvedReturnType; } + if (propertyName === TypeSystemPropertyName.ResolvedDefault) { + return (target).resolvedDefault; + } Debug.fail("Unhandled TypeSystemPropertyName " + propertyName); } @@ -3793,7 +3804,7 @@ namespace ts { function getConstructorsForTypeArguments(type: Type, typeArgumentNodes: TypeNode[]): Signature[] { const typeArgCount = typeArgumentNodes ? typeArgumentNodes.length : 0; return filter(getSignaturesOfType(type, SignatureKind.Construct), - sig => (sig.typeParameters ? sig.typeParameters.length : 0) === typeArgCount); + sig => typeArgCount >= sig.minTypeArgumentCount && typeArgCount <= (sig.typeParameters ? sig.typeParameters.length : 0)); } function getInstantiatedConstructorsForTypeArguments(type: Type, typeArgumentNodes: TypeNode[]): Signature[] { @@ -4000,6 +4011,7 @@ namespace ts { type.typeParameters = concatenate(outerTypeParameters, localTypeParameters); type.outerTypeParameters = outerTypeParameters; type.localTypeParameters = localTypeParameters; + type.minTypeArgumentCount = getMinTypeArgumentCount(localTypeParameters); (type).instantiations = createMap(); (type).instantiations[getTypeListId(type.typeParameters)] = type; (type).target = type; @@ -4043,6 +4055,7 @@ namespace ts { // Initialize the instantiation cache for generic type aliases. The declared type corresponds to // an instantiation of the type alias with the type parameters supplied as type arguments. links.typeParameters = typeParameters; + links.minTypeArgumentCount = getMinTypeArgumentCount(typeParameters); links.instantiations = createMap(); links.instantiations[getTypeListId(typeParameters)] = type; } @@ -4351,11 +4364,12 @@ namespace ts { resolveObjectTypeMembers(type, source, typeParameters, typeArguments); } - function createSignature(declaration: SignatureDeclaration, typeParameters: TypeParameter[], thisParameter: Symbol | undefined, parameters: Symbol[], + function createSignature(declaration: SignatureDeclaration, typeParameters: TypeParameter[], minTypeArgumentCount: number, thisParameter: Symbol | undefined, parameters: Symbol[], resolvedReturnType: Type, typePredicate: TypePredicate, minArgumentCount: number, hasRestParameter: boolean, hasLiteralTypes: boolean): Signature { const sig = new Signature(checker); sig.declaration = declaration; sig.typeParameters = typeParameters; + sig.minTypeArgumentCount = minTypeArgumentCount; sig.parameters = parameters; sig.thisParameter = thisParameter; sig.resolvedReturnType = resolvedReturnType; @@ -4367,7 +4381,7 @@ namespace ts { } function cloneSignature(sig: Signature): Signature { - return createSignature(sig.declaration, sig.typeParameters, sig.thisParameter, sig.parameters, sig.resolvedReturnType, + return createSignature(sig.declaration, sig.typeParameters, sig.minTypeArgumentCount, sig.thisParameter, sig.parameters, sig.resolvedReturnType, sig.typePredicate, sig.minArgumentCount, sig.hasRestParameter, sig.hasLiteralTypes); } @@ -4375,17 +4389,19 @@ namespace ts { const baseConstructorType = getBaseConstructorTypeOfClass(classType); const baseSignatures = getSignaturesOfType(baseConstructorType, SignatureKind.Construct); if (baseSignatures.length === 0) { - return [createSignature(undefined, classType.localTypeParameters, undefined, emptyArray, classType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false)]; + return [createSignature(undefined, classType.localTypeParameters, classType.minTypeArgumentCount, undefined, emptyArray, classType, /*typePredicate*/ undefined, 0, /*hasRestParameter*/ false, /*hasLiteralTypes*/ false)]; } const baseTypeNode = getBaseTypeNodeOfClass(classType); const typeArguments = map(baseTypeNode.typeArguments, getTypeFromTypeNode); const typeArgCount = typeArguments ? typeArguments.length : 0; const result: Signature[] = []; for (const baseSig of baseSignatures) { + const minTypeArgumentCount = baseSig.minTypeArgumentCount; const typeParamCount = baseSig.typeParameters ? baseSig.typeParameters.length : 0; - if (typeParamCount === typeArgCount) { - const sig = typeParamCount ? createSignatureInstantiation(baseSig, typeArguments) : cloneSignature(baseSig); + if (typeArgCount >= minTypeArgumentCount && typeArgCount <= typeParamCount) { + const sig = typeParamCount ? createSignatureInstantiation(baseSig, fillMissingTypeArguments(typeArguments, baseSig.typeParameters, minTypeArgumentCount)) : cloneSignature(baseSig); sig.typeParameters = classType.localTypeParameters; + sig.minTypeArgumentCount = classType.minTypeArgumentCount; sig.resolvedReturnType = classType; result.push(sig); } @@ -4759,11 +4775,11 @@ namespace ts { function getBaseConstraintOfType(type: TypeVariable | UnionOrIntersectionType): Type { const constraint = getResolvedBaseConstraint(type); - return constraint !== noConstraintType && constraint !== circularConstraintType ? constraint : undefined; + return constraint !== noConstraintOrDefaultType && constraint !== circularConstraintOrDefaultType ? constraint : undefined; } function hasNonCircularBaseConstraint(type: TypeVariable): boolean { - return getResolvedBaseConstraint(type) !== circularConstraintType; + return getResolvedBaseConstraint(type) !== circularConstraintOrDefaultType; } /** @@ -4777,7 +4793,7 @@ namespace ts { if (!type.resolvedBaseConstraint) { typeStack = []; const constraint = getBaseConstraint(type); - type.resolvedBaseConstraint = circular ? circularConstraintType : getTypeWithThisArgument(constraint || noConstraintType, type); + type.resolvedBaseConstraint = circular ? circularConstraintOrDefaultType : getTypeWithThisArgument(constraint || noConstraintOrDefaultType, type); } return type.resolvedBaseConstraint; @@ -4824,6 +4840,45 @@ namespace ts { } } + function getDefaultOfTypeParameter(typeParameter: TypeParameter): Type { + return hasNonCircularDefault(typeParameter) ? getDefaultFromTypeParameter(typeParameter) : undefined; + // const defaultType = getResolvedDefault(typeParameter); + // return defaultType !== noConstraintOrDefaultType && defaultType !== circularConstraintOrDefaultType ? defaultType : undefined; + } + + function hasNonCircularDefault(type: TypeParameter) { + return getResolvedDefault(type) !== circularConstraintOrDefaultType; + } + + function getResolvedDefault(typeParameter: TypeParameter) { + if (!typeParameter.resolvedDefault) { + if (!pushTypeResolution(typeParameter, TypeSystemPropertyName.ResolvedDefault)) { + return circularConstraintOrDefaultType; + } + const defaultType = getDefaultFromTypeParameter(typeParameter); + const type = defaultType && getResolvedDefaultWorker(defaultType); + if (!popTypeResolution()) { + return typeParameter.resolvedDefault = circularConstraintOrDefaultType; + } + typeParameter.resolvedDefault = type || noConstraintOrDefaultType; + } + return typeParameter.resolvedDefault; + } + + function getResolvedDefaultWorker(type: Type): Type { + if (type.flags & TypeFlags.TypeParameter) { + return getResolvedDefault(type); + } + if (type.flags & TypeFlags.UnionOrIntersection) { + const types = (type).types; + const defaultTypes = filter(map(types, getResolvedDefaultWorker), x => x !== circularConstraintOrDefaultType); + return type.flags & TypeFlags.Union && defaultTypes.length === types.length ? getUnionType(defaultTypes) : + type.flags & TypeFlags.Intersection && defaultTypes.length ? getIntersectionType(defaultTypes) : + undefined; + } + return type; + } + /** * For a type parameter, return the base constraint of the type parameter. For the string, number, * boolean, and symbol primitive types, return the corresponding object types. Otherwise return the @@ -5106,6 +5161,53 @@ namespace ts { } } + /** + * Gets the minimum number of type arguments needed to satisfy all non-optional type + * parameters. + */ + function getMinTypeArgumentCount(typeParameters: TypeParameter[] | undefined): number { + let minTypeArgumentCount = 0; + if (typeParameters) { + for (let i = 0; i < typeParameters.length; i++) { + if (!getDefaultFromTypeParameter(typeParameters[i])) { + minTypeArgumentCount = i + 1; + } + } + } + return minTypeArgumentCount; + } + + function fillMissingTypeArguments(typeArguments: Type[] | undefined, typeParameters: TypeParameter[] | undefined, minTypeArgumentCount: number) { + const numTypeArguments = typeArguments ? typeArguments.length : 0; + const numTypeParameters = typeParameters ? typeParameters.length : 0; + if (numTypeArguments >= minTypeArgumentCount && numTypeArguments <= numTypeParameters) { + if (numTypeParameters) { + if (!typeArguments) { + typeArguments = []; + } + const mapper: TypeMapper = t => { + for (let i = 0; i < numTypeParameters; i++) { + if (t === typeParameters[i]) { + if (!typeArguments[i]) { + typeArguments[i] = emptyObjectType; + const defaultType = getDefaultOfTypeParameter(typeParameters[i]); + if (defaultType) { + typeArguments[i] = instantiateType(defaultType, mapper); + } + } + return typeArguments[i]; + } + } + return t; + }; + for (let i = numTypeArguments; i < numTypeParameters; i++) { + typeArguments[i] = instantiateType(typeParameters[i], mapper); + } + } + } + return typeArguments; + } + function getSignatureFromDeclaration(declaration: SignatureDeclaration): Signature { const links = getNodeLinks(declaration); if (!links.resolvedSignature) { @@ -5172,7 +5274,7 @@ namespace ts { createTypePredicateFromTypePredicateNode(declaration.type as TypePredicateNode) : undefined; - links.resolvedSignature = createSignature(declaration, typeParameters, thisParameter, parameters, returnType, typePredicate, minArgumentCount, hasRestParameter(declaration), hasLiteralTypes); + links.resolvedSignature = createSignature(declaration, typeParameters, getMinTypeArgumentCount(typeParameters), thisParameter, parameters, returnType, typePredicate, minArgumentCount, hasRestParameter(declaration), hasLiteralTypes); } return links.resolvedSignature; } @@ -5303,6 +5405,7 @@ namespace ts { } function getSignatureInstantiation(signature: Signature, typeArguments: Type[]): Signature { + typeArguments = fillMissingTypeArguments(typeArguments, signature.typeParameters, signature.minTypeArgumentCount); const instantiations = signature.instantiations || (signature.instantiations = createMap()); const id = getTypeListId(typeArguments); return instantiations[id] || (instantiations[id] = createSignatureInstantiation(signature, typeArguments)); @@ -5381,14 +5484,28 @@ namespace ts { if (!typeParameter.constraint) { if (typeParameter.target) { const targetConstraint = getConstraintOfTypeParameter(typeParameter.target); - typeParameter.constraint = targetConstraint ? instantiateType(targetConstraint, typeParameter.mapper) : noConstraintType; + typeParameter.constraint = targetConstraint ? instantiateType(targetConstraint, typeParameter.mapper) : noConstraintOrDefaultType; } else { const constraintDeclaration = getConstraintDeclaration(typeParameter); - typeParameter.constraint = constraintDeclaration ? getTypeFromTypeNode(constraintDeclaration) : noConstraintType; + typeParameter.constraint = constraintDeclaration ? getTypeFromTypeNode(constraintDeclaration) : noConstraintOrDefaultType; } } - return typeParameter.constraint === noConstraintType ? undefined : typeParameter.constraint; + return typeParameter.constraint === noConstraintOrDefaultType ? undefined : typeParameter.constraint; + } + + function getDefaultFromTypeParameter(typeParameter: TypeParameter): Type | undefined { + if (!typeParameter.default) { + if (typeParameter.target) { + const targetDefault = getDefaultFromTypeParameter(typeParameter.target); + typeParameter.default = targetDefault ? instantiateType(targetDefault, typeParameter.mapper) : noConstraintOrDefaultType; + } + else { + const defaultDeclaration = typeParameter.symbol && forEach(typeParameter.symbol.declarations, decl => isTypeParameter(decl) && decl.default); + typeParameter.default = defaultDeclaration ? getTypeFromTypeNode(defaultDeclaration) : noConstraintOrDefaultType; + } + } + return typeParameter.default === noConstraintOrDefaultType ? undefined : typeParameter.default; } function getParentSymbolOfTypeParameter(typeParameter: TypeParameter): Symbol { @@ -5463,14 +5580,22 @@ namespace ts { const type = getDeclaredTypeOfSymbol(getMergedSymbol(symbol)); const typeParameters = type.localTypeParameters; if (typeParameters) { - if (!node.typeArguments || node.typeArguments.length !== typeParameters.length) { - error(node, Diagnostics.Generic_type_0_requires_1_type_argument_s, typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType), typeParameters.length); + const numTypeArguments = node.typeArguments ? node.typeArguments.length : 0; + if (numTypeArguments < type.minTypeArgumentCount || numTypeArguments > typeParameters.length) { + error(node, + type.minTypeArgumentCount === typeParameters.length + ? Diagnostics.Generic_type_0_requires_1_type_argument_s + : Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments, + typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType), + type.minTypeArgumentCount, + typeParameters.length); return unknownType; } // In a type reference, the outer type parameters of the referenced class or interface are automatically // supplied as type arguments and the type reference only specifies arguments for the local type parameters // of the class or interface. - return createTypeReference(type, concatenate(type.outerTypeParameters, map(node.typeArguments, getTypeFromTypeNode))); + const typeArguments = concatenate(type.outerTypeParameters, fillMissingTypeArguments(map(node.typeArguments, getTypeFromTypeNode), typeParameters, type.minTypeArgumentCount)); + return createTypeReference(type, typeArguments); } if (node.typeArguments) { error(node, Diagnostics.Type_0_is_not_generic, typeToString(type)); @@ -5492,10 +5617,17 @@ namespace ts { // declared type. Instantiations are cached using the type identities of the type arguments as the key. function getTypeFromTypeAliasReference(node: TypeReferenceNode | ExpressionWithTypeArguments | JSDocTypeReference, symbol: Symbol): Type { const type = getDeclaredTypeOfSymbol(symbol); - const typeParameters = getSymbolLinks(symbol).typeParameters; + const { typeParameters, minTypeArgumentCount } = getSymbolLinks(symbol); if (typeParameters) { - if (!node.typeArguments || node.typeArguments.length !== typeParameters.length) { - error(node, Diagnostics.Generic_type_0_requires_1_type_argument_s, symbolToString(symbol), typeParameters.length); + const numTypeArguments = node.typeArguments ? node.typeArguments.length : 0; + if (numTypeArguments < minTypeArgumentCount || numTypeArguments > typeParameters.length) { + error(node, + minTypeArgumentCount === typeParameters.length + ? Diagnostics.Generic_type_0_requires_1_type_argument_s + : Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments, + symbolToString(symbol), + minTypeArgumentCount, + typeParameters.length); return unknownType; } const typeArguments = map(node.typeArguments, getTypeFromTypeNode); @@ -5724,6 +5856,7 @@ namespace ts { type.typeParameters = typeParameters; type.outerTypeParameters = undefined; type.localTypeParameters = typeParameters; + type.minTypeArgumentCount = getMinTypeArgumentCount(typeParameters); type.instantiations = createMap(); type.instantiations[getTypeListId(type.typeParameters)] = type; type.target = type; @@ -6608,7 +6741,7 @@ namespace ts { if (signature.typePredicate) { freshTypePredicate = cloneTypePredicate(signature.typePredicate, mapper); } - const result = createSignature(signature.declaration, freshTypeParameters, + const result = createSignature(signature.declaration, freshTypeParameters, signature.minTypeArgumentCount, signature.thisParameter && instantiateSymbol(signature.thisParameter, mapper), instantiateList(signature.parameters, mapper, instantiateSymbol), instantiateType(signature.resolvedReturnType, mapper), @@ -9004,11 +9137,13 @@ namespace ts { inferenceSucceeded = !!unionOrSuperType; } else { - // Infer the empty object type when no inferences were made. It is important to remember that - // in this case, inference still succeeds, meaning there is no error for not having inference - // candidates. An inference error only occurs when there are *conflicting* candidates, i.e. + // Infer either the default or the empty object type when no inferences were + // made. It is important to remember that in this case, inference still + // succeeds, meaning there is no error for not having inference candidates. An + // inference error only occurs when there are *conflicting* candidates, i.e. // candidates with no common supertype. - inferredType = emptyObjectType; + const defaultType = getDefaultOfTypeParameter(context.signature.typeParameters[index]); + inferredType = defaultType ? instantiateType(defaultType, getInferenceMapper(context)) : emptyObjectType; inferenceSucceeded = true; } context.inferredTypes[index] = inferredType; @@ -12710,8 +12845,9 @@ namespace ts { // If the user supplied type arguments, but the number of type arguments does not match // the declared number of type parameters, the call has an incorrect arity. + const numTypeParameters = signature.typeParameters ? signature.typeParameters.length : 0; const hasRightNumberOfTypeArgs = !typeArguments || - (signature.typeParameters && typeArguments.length === signature.typeParameters.length); + (typeArguments.length >= signature.minTypeArgumentCount && typeArguments.length <= numTypeParameters); if (!hasRightNumberOfTypeArgs) { return false; } @@ -12833,7 +12969,7 @@ namespace ts { const typeParameters = signature.typeParameters; let typeArgumentsAreAssignable = true; let mapper: TypeMapper; - for (let i = 0; i < typeParameters.length; i++) { + for (let i = 0; i < typeArgumentNodes.length; i++) { if (typeArgumentsAreAssignable /* so far */) { const constraint = getConstraintOfTypeParameter(typeParameters[i]); if (constraint) { @@ -13405,23 +13541,25 @@ namespace ts { ? createInferenceContext(originalCandidate, /*inferUnionTypes*/ false) : undefined; + if (typeArguments) { + for (let i = 0; i < typeArguments.length; i++) { + inferenceContext.inferredTypes[i] = getTypeFromTypeNode(typeArguments[i]); + inferenceContext.inferences[i].isFixed = true; + } + } + while (true) { candidate = originalCandidate; if (candidate.typeParameters) { - let typeArgumentTypes: Type[]; - if (typeArguments) { - typeArgumentTypes = map(typeArguments, getTypeFromTypeNode); - typeArgumentsAreValid = checkTypeArguments(candidate, typeArguments, typeArgumentTypes, /*reportErrors*/ false); - } - else { + typeArgumentsAreValid = typeArguments ? checkTypeArguments(candidate, typeArguments, inferenceContext.inferredTypes, /*reportErrors*/ false) : true; + if (typeArgumentsAreValid) { inferTypeArguments(node, candidate, args, excludeArgument, inferenceContext); typeArgumentsAreValid = inferenceContext.failedTypeParameterIndex === undefined; - typeArgumentTypes = inferenceContext.inferredTypes; } if (!typeArgumentsAreValid) { break; } - candidate = getSignatureInstantiation(candidate, typeArgumentTypes); + candidate = getSignatureInstantiation(candidate, inferenceContext.inferredTypes); } if (!checkApplicableSignature(node, args, candidate, relation, excludeArgument, /*reportErrors*/ false)) { break; @@ -15394,11 +15532,19 @@ namespace ts { } checkSourceElement(node.constraint); + checkSourceElement(node.default); const typeParameter = getDeclaredTypeOfTypeParameter(getSymbolOfNode(node)); if (!hasNonCircularBaseConstraint(typeParameter)) { error(node.constraint, Diagnostics.Type_parameter_0_has_a_circular_constraint, typeToString(typeParameter)); } - getConstraintOfTypeParameter(getDeclaredTypeOfTypeParameter(getSymbolOfNode(node))); + if (!hasNonCircularDefault(typeParameter)) { + error(node.default, Diagnostics.Type_parameter_0_has_a_circular_default, typeToString(typeParameter)); + } + const constraintType = getConstraintOfTypeParameter(typeParameter); + const defaultType = getDefaultOfTypeParameter(typeParameter); + if (constraintType && defaultType) { + checkTypeAssignableTo(defaultType, getTypeWithThisArgument(constraintType, defaultType), node.default, Diagnostics.Type_0_does_not_satisfy_the_constraint_1); + } if (produceDiagnostics) { checkTypeNameIsReserved(node.name, Diagnostics.Type_parameter_name_cannot_be_0); } @@ -15948,7 +16094,7 @@ namespace ts { checkDecorators(node); } - function checkTypeArgumentConstraints(typeParameters: TypeParameter[], typeArgumentNodes: TypeNode[]): boolean { + function checkTypeArgumentConstraints(typeParameters: TypeParameter[], typeArgumentNodes: TypeNode[], minTypeArgumentCount: number): boolean { let typeArguments: Type[]; let mapper: TypeMapper; let result = true; @@ -15956,7 +16102,7 @@ namespace ts { const constraint = getConstraintOfTypeParameter(typeParameters[i]); if (constraint) { if (!typeArguments) { - typeArguments = map(typeArgumentNodes, getTypeFromTypeNode); + typeArguments = fillMissingTypeArguments(map(typeArgumentNodes, getTypeFromTypeNode), typeParameters, minTypeArgumentCount); mapper = createTypeMapper(typeParameters, typeArguments); } const typeArgument = typeArguments[i]; @@ -15980,7 +16126,8 @@ namespace ts { if (produceDiagnostics) { const symbol = getNodeLinks(node).resolvedSymbol; const typeParameters = symbol.flags & SymbolFlags.TypeAlias ? getSymbolLinks(symbol).typeParameters : (type).target.localTypeParameters; - checkTypeArgumentConstraints(typeParameters, node.typeArguments); + const minTypeArgumentCount = symbol.flags & SymbolFlags.TypeAlias ? getSymbolLinks(symbol).minTypeArgumentCount : (type).target.minTypeArgumentCount; + checkTypeArgumentConstraints(typeParameters, node.typeArguments, minTypeArgumentCount); } } if (type.flags & TypeFlags.Enum && !(type).memberTypes && getNodeLinks(node).resolvedSymbol.flags & SymbolFlags.EnumMember) { @@ -18182,14 +18329,23 @@ namespace ts { } } - /** Check each type parameter and check that type parameters have no duplicate type parameter declarations */ + /** + * Check each type parameter and check that type parameters have no duplicate type parameter declarations + */ function checkTypeParameters(typeParameterDeclarations: TypeParameterDeclaration[]) { if (typeParameterDeclarations) { + let seenDefault = false; for (let i = 0; i < typeParameterDeclarations.length; i++) { const node = typeParameterDeclarations[i]; checkTypeParameter(node); if (produceDiagnostics) { + if (node.default) { + seenDefault = true; + } + else if (seenDefault) { + error(node, Diagnostics.Required_type_parameters_may_not_follow_optional_type_parameters); + } for (let j = 0; j < i; j++) { if (typeParameterDeclarations[j].symbol === node.symbol) { error(node.name, Diagnostics.Duplicate_identifier_0, declarationNameToString(node.name)); @@ -18273,7 +18429,7 @@ namespace ts { if (baseTypeNode.typeArguments) { forEach(baseTypeNode.typeArguments, checkSourceElement); for (const constructor of getConstructorsForTypeArguments(staticBaseType, baseTypeNode.typeArguments)) { - if (!checkTypeArgumentConstraints(constructor.typeParameters, baseTypeNode.typeArguments)) { + if (!checkTypeArgumentConstraints(constructor.typeParameters, baseTypeNode.typeArguments, constructor.minTypeArgumentCount)) { break; } } @@ -18472,14 +18628,15 @@ namespace ts { if (tp1.name.text !== tp2.name.text) { return false; } - if (!tp1.constraint && !tp2.constraint) { - continue; + if (tp1.constraint || tp2.constraint) { + if (!tp1.constraint || !tp2.constraint || !isTypeIdenticalTo(getTypeFromTypeNode(tp1.constraint), getTypeFromTypeNode(tp2.constraint))) { + return false; + } } - if (!tp1.constraint || !tp2.constraint) { - return false; - } - if (!isTypeIdenticalTo(getTypeFromTypeNode(tp1.constraint), getTypeFromTypeNode(tp2.constraint))) { - return false; + if (tp1.default || tp2.default) { + if (!tp1.default || !tp2.default || !isTypeIdenticalTo(getTypeFromTypeNode(tp1.default), getTypeFromTypeNode(tp2.default))) { + return false; + } } } return true; diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index cd98622e080..240ef647fb3 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -1000,6 +1000,23 @@ namespace ts { emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.constraint, getTypeParameterConstraintVisibilityError); } } + if (node.default && !isPrivateMethodTypeParameter(node)) { + write(" = "); + if (node.parent.kind === SyntaxKind.FunctionType || + node.parent.kind === SyntaxKind.ConstructorType || + (node.parent.parent && node.parent.parent.kind === SyntaxKind.TypeLiteral)) { + Debug.assert(node.parent.kind === SyntaxKind.MethodDeclaration || + node.parent.kind === SyntaxKind.MethodSignature || + node.parent.kind === SyntaxKind.FunctionType || + node.parent.kind === SyntaxKind.ConstructorType || + node.parent.kind === SyntaxKind.CallSignature || + node.parent.kind === SyntaxKind.ConstructSignature); + emitType(node.default); + } + else { + emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.default, getTypeParameterConstraintVisibilityError); + } + } function getTypeParameterConstraintVisibilityError(): SymbolAccessibilityDiagnostic { // Type parameter constraints are named by user so we should always be able to name it diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 52fc401d1f1..0d8479eea96 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -2035,6 +2035,18 @@ "category": "Error", "code": 2704 }, + "Required type parameters may not follow optional type parameters": { + "category": "Error", + "code": 2705 + }, + "Type parameter '{0}' has a circular default.": { + "category": "Error", + "code": 2706 + }, + "Generic type '{0}' requires between {1} and {2} type arguments": { + "category": "Error", + "code": 2707 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 026f844315b..6ac417419de 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -66,6 +66,7 @@ namespace ts { case SyntaxKind.TypeParameter: return visitNode(cbNode, (node).name) || visitNode(cbNode, (node).constraint) || + visitNode(cbNode, (node).default) || visitNode(cbNode, (node).expression); case SyntaxKind.ShorthandPropertyAssignment: return visitNodes(cbNodes, node.decorators) || @@ -2098,6 +2099,10 @@ namespace ts { } } + if (parseOptional(SyntaxKind.EqualsToken)) { + node.default = parseType(); + } + return finishNode(node); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 954ad21ba29..30a054d481e 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -604,6 +604,7 @@ namespace ts { kind: SyntaxKind.TypeParameter; name: Identifier; constraint?: TypeNode; + default?: TypeNode; // For error recovery purposes. expression?: Expression; @@ -2679,6 +2680,7 @@ namespace ts { type?: Type; // Type of value symbol declaredType?: Type; // Type of class, interface, enum, type alias, or type parameter typeParameters?: TypeParameter[]; // Type parameters of type alias (undefined if non-generic) + minTypeArgumentCount?: number; inferredClassType?: Type; // Type of an inferred ES5 class instantiations?: Map; // Instantiations of generic type alias (undefined if non-generic) mapper?: TypeMapper; // Type mapper for instantiation alias @@ -2880,6 +2882,8 @@ namespace ts { typeParameters: TypeParameter[]; // Type parameters (undefined if non-generic) outerTypeParameters: TypeParameter[]; // Outer type parameters (undefined if none) localTypeParameters: TypeParameter[]; // Local type parameters (undefined if none) + /* @internal */ + minTypeArgumentCount: number; thisType: TypeParameter; // The "this" type (undefined if none) /* @internal */ resolvedBaseConstructorType?: Type; // Resolved base constructor type of class @@ -2986,18 +2990,23 @@ namespace ts { /* @internal */ resolvedBaseConstraint: Type; /* @internal */ + resolvedDefault: Type; + /* @internal */ resolvedIndexType: IndexType; } // Type parameters (TypeFlags.TypeParameter) export interface TypeParameter extends TypeVariable { constraint: Type; // Constraint + default?: Type; /* @internal */ target?: TypeParameter; // Instantiation target /* @internal */ mapper?: TypeMapper; // Instantiation mapper /* @internal */ isThisType?: boolean; + /* @internal */ + resolvedDefaultType?: Type; } // Indexed access types (TypeFlags.IndexedAccess) @@ -3021,6 +3030,8 @@ namespace ts { export interface Signature { declaration: SignatureDeclaration; // Originating declaration typeParameters: TypeParameter[]; // Type parameters (undefined if non-generic) + /* @internal */ + minTypeArgumentCount: number; // Number of non-optional type parameters parameters: Symbol[]; // Parameters /* @internal */ thisParameter?: Symbol; // symbol of this-type parameter diff --git a/src/services/services.ts b/src/services/services.ts index fac7715033b..850ac3b4017 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -396,6 +396,7 @@ namespace ts { parameters: Symbol[]; thisParameter: Symbol; resolvedReturnType: Type; + minTypeArgumentCount: number; minArgumentCount: number; hasRestParameter: boolean; hasLiteralTypes: boolean; diff --git a/tests/baselines/reference/genericDefaults.js b/tests/baselines/reference/genericDefaults.js new file mode 100644 index 00000000000..aeedbd5d9e1 --- /dev/null +++ b/tests/baselines/reference/genericDefaults.js @@ -0,0 +1,238 @@ +//// [genericDefaults.ts] +declare const x: any; + +declare function f00(a?: T): T; +const f00c00 = f00(); +const f00c01 = f00(1); +const f00c02 = f00("a"); +const f00c03 = f00(); +const f00c04 = f00(1); +const f00c05 = f00("a"); + +declare function f01(a?: T, b?: U): [T, U]; +const f01c00 = f01(); +const f01c01 = f01(1); +const f01c02 = f01(1, "a"); +const f01c03 = f01(); +const f01c04 = f01(1); +const f01c05 = f01(1, "a"); +const f01c06 = f01(); +const f01c07 = f01(1); +const f01c08 = f01(1, "a"); + +declare function f02(a?: T, b?: U): [T, U]; +const f02c00 = f02(); +const f02c01 = f02(1); +const f02c02 = f02(1, "a"); +const f02c03 = f02(); +const f02c04 = f02(1); +const f02c05 = f02(1, "a"); +const f02c06 = f02(); +const f02c07 = f02(1); +const f02c08 = f02(1, "a"); + +declare function f03(a?: T, b?: U): [T, U]; +const f03c00 = f03(); +const f03c01 = f03(1); +const f03c02 = f03(1, 1); +const f03c03 = f03(); +const f03c04 = f03(1); +const f03c05 = f03(1, 2); +const f03c06 = f03(); +const f03c07 = f03(1); +const f03c08 = f03(1, 2); + +interface i00 { a: T; } +const i00c00 = (x).a; +const i00c01 = (>x).a; + +interface i01 { a: [T, U]; } +const i01c00 = (>x).a; +const i01c01 = (>x).a; + +interface i02 { a: [T, U]; } +const i02c00 = (>x).a; +const i02c01 = (>x).a; +const i02c02 = (>x).a; +const i02c03 = (>x).a; +const i02c04 = (>x).a; + +interface i03 { a: [T, U]; } +const i03c00 = (>x).a; +const i03c01 = (>x).a; +const i03c02 = (>x).a; +const i03c03 = (>x).a; +const i03c04 = (>x).a; + +interface Base01 { a: T; } +interface Base01Constructor { new (a?: T): Base01; } + +declare const Base01: Base01Constructor; +const Base01c00 = new Base01(); +const Base01c01 = new Base01(1); +const Base01c02 = new Base01(); +const Base01c03 = new Base01(1); + +declare class Derived01 extends Base01 { } +const Derived01c00 = new Derived01(); +const Derived01c01 = new Derived01(1); +const Derived01c02 = new Derived01(); +const Derived01c03 = new Derived01(1); + +declare class Derived02 extends Base01 { } +const Derived02c00 = new Derived02(); +const Derived02c01 = new Derived02(1); +const Derived02c02 = new Derived02(); +const Derived02c03 = new Derived02(1); + + +//// [genericDefaults.js] +var f00c00 = f00(); +var f00c01 = f00(1); +var f00c02 = f00("a"); +var f00c03 = f00(); +var f00c04 = f00(1); +var f00c05 = f00("a"); +var f01c00 = f01(); +var f01c01 = f01(1); +var f01c02 = f01(1, "a"); +var f01c03 = f01(); +var f01c04 = f01(1); +var f01c05 = f01(1, "a"); +var f01c06 = f01(); +var f01c07 = f01(1); +var f01c08 = f01(1, "a"); +var f02c00 = f02(); +var f02c01 = f02(1); +var f02c02 = f02(1, "a"); +var f02c03 = f02(); +var f02c04 = f02(1); +var f02c05 = f02(1, "a"); +var f02c06 = f02(); +var f02c07 = f02(1); +var f02c08 = f02(1, "a"); +var f03c00 = f03(); +var f03c01 = f03(1); +var f03c02 = f03(1, 1); +var f03c03 = f03(); +var f03c04 = f03(1); +var f03c05 = f03(1, 2); +var f03c06 = f03(); +var f03c07 = f03(1); +var f03c08 = f03(1, 2); +var i00c00 = x.a; +var i00c01 = x.a; +var i01c00 = x.a; +var i01c01 = x.a; +var i02c00 = x.a; +var i02c01 = x.a; +var i02c02 = x.a; +var i02c03 = x.a; +var i02c04 = x.a; +var i03c00 = x.a; +var i03c01 = x.a; +var i03c02 = x.a; +var i03c03 = x.a; +var i03c04 = x.a; +var Base01c00 = new Base01(); +var Base01c01 = new Base01(1); +var Base01c02 = new Base01(); +var Base01c03 = new Base01(1); +var Derived01c00 = new Derived01(); +var Derived01c01 = new Derived01(1); +var Derived01c02 = new Derived01(); +var Derived01c03 = new Derived01(1); +var Derived02c00 = new Derived02(); +var Derived02c01 = new Derived02(1); +var Derived02c02 = new Derived02(); +var Derived02c03 = new Derived02(1); + + +//// [genericDefaults.d.ts] +declare const x: any; +declare function f00(a?: T): T; +declare const f00c00: number; +declare const f00c01 = 1; +declare const f00c02 = "a"; +declare const f00c03: number; +declare const f00c04: number; +declare const f00c05: string; +declare function f01(a?: T, b?: U): [T, U]; +declare const f01c00: [{}, {}]; +declare const f01c01: [number, number]; +declare const f01c02: [number, string]; +declare const f01c03: [number, number]; +declare const f01c04: [number, number]; +declare const f01c05: [number, string]; +declare const f01c06: [number, string]; +declare const f01c07: [number, string]; +declare const f01c08: [number, string]; +declare function f02(a?: T, b?: U): [T, U]; +declare const f02c00: [number, number]; +declare const f02c01: [1, 1]; +declare const f02c02: [1, string]; +declare const f02c03: [number, number]; +declare const f02c04: [number, number]; +declare const f02c05: [number, string]; +declare const f02c06: [number, string]; +declare const f02c07: [number, string]; +declare const f02c08: [number, string]; +declare function f03(a?: T, b?: U): [T, U]; +declare const f03c00: [number, number]; +declare const f03c01: [1, 1]; +declare const f03c02: [1, 1]; +declare const f03c03: [number, number]; +declare const f03c04: [number, number]; +declare const f03c05: [number, number]; +declare const f03c06: [number, number]; +declare const f03c07: [number, number]; +declare const f03c08: [number, number]; +interface i00 { + a: T; +} +declare const i00c00: number; +declare const i00c01: number; +interface i01 { + a: [T, U]; +} +declare const i01c00: [number, number]; +declare const i01c01: [number, string]; +interface i02 { + a: [T, U]; +} +declare const i02c00: [number, number]; +declare const i02c01: [1, 1]; +declare const i02c02: [number, number]; +declare const i02c03: [1, number]; +declare const i02c04: [number, 1]; +interface i03 { + a: [T, U]; +} +declare const i03c00: [number, number]; +declare const i03c01: [1, 1]; +declare const i03c02: [number, number]; +declare const i03c03: [1, 1]; +declare const i03c04: [number, 1]; +interface Base01 { + a: T; +} +interface Base01Constructor { + new (a?: T): Base01; +} +declare const Base01: Base01Constructor; +declare const Base01c00: Base01; +declare const Base01c01: Base01; +declare const Base01c02: Base01; +declare const Base01c03: Base01; +declare class Derived01 extends Base01 { +} +declare const Derived01c00: Derived01<{}>; +declare const Derived01c01: Derived01; +declare const Derived01c02: Derived01; +declare const Derived01c03: Derived01; +declare class Derived02 extends Base01 { +} +declare const Derived02c00: Derived02; +declare const Derived02c01: Derived02; +declare const Derived02c02: Derived02; +declare const Derived02c03: Derived02; diff --git a/tests/baselines/reference/genericDefaults.symbols b/tests/baselines/reference/genericDefaults.symbols new file mode 100644 index 00000000000..fe8dff0412e --- /dev/null +++ b/tests/baselines/reference/genericDefaults.symbols @@ -0,0 +1,390 @@ +=== tests/cases/compiler/genericDefaults.ts === +declare const x: any; +>x : Symbol(x, Decl(genericDefaults.ts, 0, 13)) + +declare function f00(a?: T): T; +>f00 : Symbol(f00, Decl(genericDefaults.ts, 0, 21)) +>T : Symbol(T, Decl(genericDefaults.ts, 2, 21)) +>a : Symbol(a, Decl(genericDefaults.ts, 2, 33)) +>T : Symbol(T, Decl(genericDefaults.ts, 2, 21)) +>T : Symbol(T, Decl(genericDefaults.ts, 2, 21)) + +const f00c00 = f00(); +>f00c00 : Symbol(f00c00, Decl(genericDefaults.ts, 3, 5)) +>f00 : Symbol(f00, Decl(genericDefaults.ts, 0, 21)) + +const f00c01 = f00(1); +>f00c01 : Symbol(f00c01, Decl(genericDefaults.ts, 4, 5)) +>f00 : Symbol(f00, Decl(genericDefaults.ts, 0, 21)) + +const f00c02 = f00("a"); +>f00c02 : Symbol(f00c02, Decl(genericDefaults.ts, 5, 5)) +>f00 : Symbol(f00, Decl(genericDefaults.ts, 0, 21)) + +const f00c03 = f00(); +>f00c03 : Symbol(f00c03, Decl(genericDefaults.ts, 6, 5)) +>f00 : Symbol(f00, Decl(genericDefaults.ts, 0, 21)) + +const f00c04 = f00(1); +>f00c04 : Symbol(f00c04, Decl(genericDefaults.ts, 7, 5)) +>f00 : Symbol(f00, Decl(genericDefaults.ts, 0, 21)) + +const f00c05 = f00("a"); +>f00c05 : Symbol(f00c05, Decl(genericDefaults.ts, 8, 5)) +>f00 : Symbol(f00, Decl(genericDefaults.ts, 0, 21)) + +declare function f01(a?: T, b?: U): [T, U]; +>f01 : Symbol(f01, Decl(genericDefaults.ts, 8, 32)) +>T : Symbol(T, Decl(genericDefaults.ts, 10, 21)) +>U : Symbol(U, Decl(genericDefaults.ts, 10, 23)) +>T : Symbol(T, Decl(genericDefaults.ts, 10, 21)) +>a : Symbol(a, Decl(genericDefaults.ts, 10, 31)) +>T : Symbol(T, Decl(genericDefaults.ts, 10, 21)) +>b : Symbol(b, Decl(genericDefaults.ts, 10, 37)) +>U : Symbol(U, Decl(genericDefaults.ts, 10, 23)) +>T : Symbol(T, Decl(genericDefaults.ts, 10, 21)) +>U : Symbol(U, Decl(genericDefaults.ts, 10, 23)) + +const f01c00 = f01(); +>f01c00 : Symbol(f01c00, Decl(genericDefaults.ts, 11, 5)) +>f01 : Symbol(f01, Decl(genericDefaults.ts, 8, 32)) + +const f01c01 = f01(1); +>f01c01 : Symbol(f01c01, Decl(genericDefaults.ts, 12, 5)) +>f01 : Symbol(f01, Decl(genericDefaults.ts, 8, 32)) + +const f01c02 = f01(1, "a"); +>f01c02 : Symbol(f01c02, Decl(genericDefaults.ts, 13, 5)) +>f01 : Symbol(f01, Decl(genericDefaults.ts, 8, 32)) + +const f01c03 = f01(); +>f01c03 : Symbol(f01c03, Decl(genericDefaults.ts, 14, 5)) +>f01 : Symbol(f01, Decl(genericDefaults.ts, 8, 32)) + +const f01c04 = f01(1); +>f01c04 : Symbol(f01c04, Decl(genericDefaults.ts, 15, 5)) +>f01 : Symbol(f01, Decl(genericDefaults.ts, 8, 32)) + +const f01c05 = f01(1, "a"); +>f01c05 : Symbol(f01c05, Decl(genericDefaults.ts, 16, 5)) +>f01 : Symbol(f01, Decl(genericDefaults.ts, 8, 32)) + +const f01c06 = f01(); +>f01c06 : Symbol(f01c06, Decl(genericDefaults.ts, 17, 5)) +>f01 : Symbol(f01, Decl(genericDefaults.ts, 8, 32)) + +const f01c07 = f01(1); +>f01c07 : Symbol(f01c07, Decl(genericDefaults.ts, 18, 5)) +>f01 : Symbol(f01, Decl(genericDefaults.ts, 8, 32)) + +const f01c08 = f01(1, "a"); +>f01c08 : Symbol(f01c08, Decl(genericDefaults.ts, 19, 5)) +>f01 : Symbol(f01, Decl(genericDefaults.ts, 8, 32)) + +declare function f02(a?: T, b?: U): [T, U]; +>f02 : Symbol(f02, Decl(genericDefaults.ts, 19, 43)) +>T : Symbol(T, Decl(genericDefaults.ts, 21, 21)) +>U : Symbol(U, Decl(genericDefaults.ts, 21, 38)) +>T : Symbol(T, Decl(genericDefaults.ts, 21, 21)) +>a : Symbol(a, Decl(genericDefaults.ts, 21, 46)) +>T : Symbol(T, Decl(genericDefaults.ts, 21, 21)) +>b : Symbol(b, Decl(genericDefaults.ts, 21, 52)) +>U : Symbol(U, Decl(genericDefaults.ts, 21, 38)) +>T : Symbol(T, Decl(genericDefaults.ts, 21, 21)) +>U : Symbol(U, Decl(genericDefaults.ts, 21, 38)) + +const f02c00 = f02(); +>f02c00 : Symbol(f02c00, Decl(genericDefaults.ts, 22, 5)) +>f02 : Symbol(f02, Decl(genericDefaults.ts, 19, 43)) + +const f02c01 = f02(1); +>f02c01 : Symbol(f02c01, Decl(genericDefaults.ts, 23, 5)) +>f02 : Symbol(f02, Decl(genericDefaults.ts, 19, 43)) + +const f02c02 = f02(1, "a"); +>f02c02 : Symbol(f02c02, Decl(genericDefaults.ts, 24, 5)) +>f02 : Symbol(f02, Decl(genericDefaults.ts, 19, 43)) + +const f02c03 = f02(); +>f02c03 : Symbol(f02c03, Decl(genericDefaults.ts, 25, 5)) +>f02 : Symbol(f02, Decl(genericDefaults.ts, 19, 43)) + +const f02c04 = f02(1); +>f02c04 : Symbol(f02c04, Decl(genericDefaults.ts, 26, 5)) +>f02 : Symbol(f02, Decl(genericDefaults.ts, 19, 43)) + +const f02c05 = f02(1, "a"); +>f02c05 : Symbol(f02c05, Decl(genericDefaults.ts, 27, 5)) +>f02 : Symbol(f02, Decl(genericDefaults.ts, 19, 43)) + +const f02c06 = f02(); +>f02c06 : Symbol(f02c06, Decl(genericDefaults.ts, 28, 5)) +>f02 : Symbol(f02, Decl(genericDefaults.ts, 19, 43)) + +const f02c07 = f02(1); +>f02c07 : Symbol(f02c07, Decl(genericDefaults.ts, 29, 5)) +>f02 : Symbol(f02, Decl(genericDefaults.ts, 19, 43)) + +const f02c08 = f02(1, "a"); +>f02c08 : Symbol(f02c08, Decl(genericDefaults.ts, 30, 5)) +>f02 : Symbol(f02, Decl(genericDefaults.ts, 19, 43)) + +declare function f03(a?: T, b?: U): [T, U]; +>f03 : Symbol(f03, Decl(genericDefaults.ts, 30, 43)) +>T : Symbol(T, Decl(genericDefaults.ts, 32, 21)) +>U : Symbol(U, Decl(genericDefaults.ts, 32, 38)) +>T : Symbol(T, Decl(genericDefaults.ts, 32, 21)) +>T : Symbol(T, Decl(genericDefaults.ts, 32, 21)) +>a : Symbol(a, Decl(genericDefaults.ts, 32, 56)) +>T : Symbol(T, Decl(genericDefaults.ts, 32, 21)) +>b : Symbol(b, Decl(genericDefaults.ts, 32, 62)) +>U : Symbol(U, Decl(genericDefaults.ts, 32, 38)) +>T : Symbol(T, Decl(genericDefaults.ts, 32, 21)) +>U : Symbol(U, Decl(genericDefaults.ts, 32, 38)) + +const f03c00 = f03(); +>f03c00 : Symbol(f03c00, Decl(genericDefaults.ts, 33, 5)) +>f03 : Symbol(f03, Decl(genericDefaults.ts, 30, 43)) + +const f03c01 = f03(1); +>f03c01 : Symbol(f03c01, Decl(genericDefaults.ts, 34, 5)) +>f03 : Symbol(f03, Decl(genericDefaults.ts, 30, 43)) + +const f03c02 = f03(1, 1); +>f03c02 : Symbol(f03c02, Decl(genericDefaults.ts, 35, 5)) +>f03 : Symbol(f03, Decl(genericDefaults.ts, 30, 43)) + +const f03c03 = f03(); +>f03c03 : Symbol(f03c03, Decl(genericDefaults.ts, 36, 5)) +>f03 : Symbol(f03, Decl(genericDefaults.ts, 30, 43)) + +const f03c04 = f03(1); +>f03c04 : Symbol(f03c04, Decl(genericDefaults.ts, 37, 5)) +>f03 : Symbol(f03, Decl(genericDefaults.ts, 30, 43)) + +const f03c05 = f03(1, 2); +>f03c05 : Symbol(f03c05, Decl(genericDefaults.ts, 38, 5)) +>f03 : Symbol(f03, Decl(genericDefaults.ts, 30, 43)) + +const f03c06 = f03(); +>f03c06 : Symbol(f03c06, Decl(genericDefaults.ts, 39, 5)) +>f03 : Symbol(f03, Decl(genericDefaults.ts, 30, 43)) + +const f03c07 = f03(1); +>f03c07 : Symbol(f03c07, Decl(genericDefaults.ts, 40, 5)) +>f03 : Symbol(f03, Decl(genericDefaults.ts, 30, 43)) + +const f03c08 = f03(1, 2); +>f03c08 : Symbol(f03c08, Decl(genericDefaults.ts, 41, 5)) +>f03 : Symbol(f03, Decl(genericDefaults.ts, 30, 43)) + +interface i00 { a: T; } +>i00 : Symbol(i00, Decl(genericDefaults.ts, 41, 41)) +>T : Symbol(T, Decl(genericDefaults.ts, 43, 14)) +>a : Symbol(i00.a, Decl(genericDefaults.ts, 43, 27)) +>T : Symbol(T, Decl(genericDefaults.ts, 43, 14)) + +const i00c00 = (x).a; +>i00c00 : Symbol(i00c00, Decl(genericDefaults.ts, 44, 5)) +>(x).a : Symbol(i00.a, Decl(genericDefaults.ts, 43, 27)) +>i00 : Symbol(i00, Decl(genericDefaults.ts, 41, 41)) +>x : Symbol(x, Decl(genericDefaults.ts, 0, 13)) +>a : Symbol(i00.a, Decl(genericDefaults.ts, 43, 27)) + +const i00c01 = (>x).a; +>i00c01 : Symbol(i00c01, Decl(genericDefaults.ts, 45, 5)) +>(>x).a : Symbol(i00.a, Decl(genericDefaults.ts, 43, 27)) +>i00 : Symbol(i00, Decl(genericDefaults.ts, 41, 41)) +>x : Symbol(x, Decl(genericDefaults.ts, 0, 13)) +>a : Symbol(i00.a, Decl(genericDefaults.ts, 43, 27)) + +interface i01 { a: [T, U]; } +>i01 : Symbol(i01, Decl(genericDefaults.ts, 45, 34)) +>T : Symbol(T, Decl(genericDefaults.ts, 47, 14)) +>U : Symbol(U, Decl(genericDefaults.ts, 47, 16)) +>T : Symbol(T, Decl(genericDefaults.ts, 47, 14)) +>a : Symbol(i01.a, Decl(genericDefaults.ts, 47, 25)) +>T : Symbol(T, Decl(genericDefaults.ts, 47, 14)) +>U : Symbol(U, Decl(genericDefaults.ts, 47, 16)) + +const i01c00 = (>x).a; +>i01c00 : Symbol(i01c00, Decl(genericDefaults.ts, 48, 5)) +>(>x).a : Symbol(i01.a, Decl(genericDefaults.ts, 47, 25)) +>i01 : Symbol(i01, Decl(genericDefaults.ts, 45, 34)) +>x : Symbol(x, Decl(genericDefaults.ts, 0, 13)) +>a : Symbol(i01.a, Decl(genericDefaults.ts, 47, 25)) + +const i01c01 = (>x).a; +>i01c01 : Symbol(i01c01, Decl(genericDefaults.ts, 49, 5)) +>(>x).a : Symbol(i01.a, Decl(genericDefaults.ts, 47, 25)) +>i01 : Symbol(i01, Decl(genericDefaults.ts, 45, 34)) +>x : Symbol(x, Decl(genericDefaults.ts, 0, 13)) +>a : Symbol(i01.a, Decl(genericDefaults.ts, 47, 25)) + +interface i02 { a: [T, U]; } +>i02 : Symbol(i02, Decl(genericDefaults.ts, 49, 42)) +>T : Symbol(T, Decl(genericDefaults.ts, 51, 14)) +>U : Symbol(U, Decl(genericDefaults.ts, 51, 31)) +>T : Symbol(T, Decl(genericDefaults.ts, 51, 14)) +>a : Symbol(i02.a, Decl(genericDefaults.ts, 51, 40)) +>T : Symbol(T, Decl(genericDefaults.ts, 51, 14)) +>U : Symbol(U, Decl(genericDefaults.ts, 51, 31)) + +const i02c00 = (>x).a; +>i02c00 : Symbol(i02c00, Decl(genericDefaults.ts, 52, 5)) +>(>x).a : Symbol(i02.a, Decl(genericDefaults.ts, 51, 40)) +>i02 : Symbol(i02, Decl(genericDefaults.ts, 49, 42)) +>x : Symbol(x, Decl(genericDefaults.ts, 0, 13)) +>a : Symbol(i02.a, Decl(genericDefaults.ts, 51, 40)) + +const i02c01 = (>x).a; +>i02c01 : Symbol(i02c01, Decl(genericDefaults.ts, 53, 5)) +>(>x).a : Symbol(i02.a, Decl(genericDefaults.ts, 51, 40)) +>i02 : Symbol(i02, Decl(genericDefaults.ts, 49, 42)) +>x : Symbol(x, Decl(genericDefaults.ts, 0, 13)) +>a : Symbol(i02.a, Decl(genericDefaults.ts, 51, 40)) + +const i02c02 = (>x).a; +>i02c02 : Symbol(i02c02, Decl(genericDefaults.ts, 54, 5)) +>(>x).a : Symbol(i02.a, Decl(genericDefaults.ts, 51, 40)) +>i02 : Symbol(i02, Decl(genericDefaults.ts, 49, 42)) +>x : Symbol(x, Decl(genericDefaults.ts, 0, 13)) +>a : Symbol(i02.a, Decl(genericDefaults.ts, 51, 40)) + +const i02c03 = (>x).a; +>i02c03 : Symbol(i02c03, Decl(genericDefaults.ts, 55, 5)) +>(>x).a : Symbol(i02.a, Decl(genericDefaults.ts, 51, 40)) +>i02 : Symbol(i02, Decl(genericDefaults.ts, 49, 42)) +>x : Symbol(x, Decl(genericDefaults.ts, 0, 13)) +>a : Symbol(i02.a, Decl(genericDefaults.ts, 51, 40)) + +const i02c04 = (>x).a; +>i02c04 : Symbol(i02c04, Decl(genericDefaults.ts, 56, 5)) +>(>x).a : Symbol(i02.a, Decl(genericDefaults.ts, 51, 40)) +>i02 : Symbol(i02, Decl(genericDefaults.ts, 49, 42)) +>x : Symbol(x, Decl(genericDefaults.ts, 0, 13)) +>a : Symbol(i02.a, Decl(genericDefaults.ts, 51, 40)) + +interface i03 { a: [T, U]; } +>i03 : Symbol(i03, Decl(genericDefaults.ts, 56, 37)) +>T : Symbol(T, Decl(genericDefaults.ts, 58, 14)) +>U : Symbol(U, Decl(genericDefaults.ts, 58, 31)) +>T : Symbol(T, Decl(genericDefaults.ts, 58, 14)) +>T : Symbol(T, Decl(genericDefaults.ts, 58, 14)) +>a : Symbol(i03.a, Decl(genericDefaults.ts, 58, 50)) +>T : Symbol(T, Decl(genericDefaults.ts, 58, 14)) +>U : Symbol(U, Decl(genericDefaults.ts, 58, 31)) + +const i03c00 = (>x).a; +>i03c00 : Symbol(i03c00, Decl(genericDefaults.ts, 59, 5)) +>(>x).a : Symbol(i03.a, Decl(genericDefaults.ts, 58, 50)) +>i03 : Symbol(i03, Decl(genericDefaults.ts, 56, 37)) +>x : Symbol(x, Decl(genericDefaults.ts, 0, 13)) +>a : Symbol(i03.a, Decl(genericDefaults.ts, 58, 50)) + +const i03c01 = (>x).a; +>i03c01 : Symbol(i03c01, Decl(genericDefaults.ts, 60, 5)) +>(>x).a : Symbol(i03.a, Decl(genericDefaults.ts, 58, 50)) +>i03 : Symbol(i03, Decl(genericDefaults.ts, 56, 37)) +>x : Symbol(x, Decl(genericDefaults.ts, 0, 13)) +>a : Symbol(i03.a, Decl(genericDefaults.ts, 58, 50)) + +const i03c02 = (>x).a; +>i03c02 : Symbol(i03c02, Decl(genericDefaults.ts, 61, 5)) +>(>x).a : Symbol(i03.a, Decl(genericDefaults.ts, 58, 50)) +>i03 : Symbol(i03, Decl(genericDefaults.ts, 56, 37)) +>x : Symbol(x, Decl(genericDefaults.ts, 0, 13)) +>a : Symbol(i03.a, Decl(genericDefaults.ts, 58, 50)) + +const i03c03 = (>x).a; +>i03c03 : Symbol(i03c03, Decl(genericDefaults.ts, 62, 5)) +>(>x).a : Symbol(i03.a, Decl(genericDefaults.ts, 58, 50)) +>i03 : Symbol(i03, Decl(genericDefaults.ts, 56, 37)) +>x : Symbol(x, Decl(genericDefaults.ts, 0, 13)) +>a : Symbol(i03.a, Decl(genericDefaults.ts, 58, 50)) + +const i03c04 = (>x).a; +>i03c04 : Symbol(i03c04, Decl(genericDefaults.ts, 63, 5)) +>(>x).a : Symbol(i03.a, Decl(genericDefaults.ts, 58, 50)) +>i03 : Symbol(i03, Decl(genericDefaults.ts, 56, 37)) +>x : Symbol(x, Decl(genericDefaults.ts, 0, 13)) +>a : Symbol(i03.a, Decl(genericDefaults.ts, 58, 50)) + +interface Base01 { a: T; } +>Base01 : Symbol(Base01, Decl(genericDefaults.ts, 63, 37), Decl(genericDefaults.ts, 68, 13)) +>T : Symbol(T, Decl(genericDefaults.ts, 65, 17)) +>a : Symbol(Base01.a, Decl(genericDefaults.ts, 65, 21)) +>T : Symbol(T, Decl(genericDefaults.ts, 65, 17)) + +interface Base01Constructor { new (a?: T): Base01; } +>Base01Constructor : Symbol(Base01Constructor, Decl(genericDefaults.ts, 65, 29)) +>T : Symbol(T, Decl(genericDefaults.ts, 66, 35)) +>a : Symbol(a, Decl(genericDefaults.ts, 66, 47)) +>T : Symbol(T, Decl(genericDefaults.ts, 66, 35)) +>Base01 : Symbol(Base01, Decl(genericDefaults.ts, 63, 37), Decl(genericDefaults.ts, 68, 13)) +>T : Symbol(T, Decl(genericDefaults.ts, 66, 35)) + +declare const Base01: Base01Constructor; +>Base01 : Symbol(Base01, Decl(genericDefaults.ts, 63, 37), Decl(genericDefaults.ts, 68, 13)) +>Base01Constructor : Symbol(Base01Constructor, Decl(genericDefaults.ts, 65, 29)) + +const Base01c00 = new Base01(); +>Base01c00 : Symbol(Base01c00, Decl(genericDefaults.ts, 69, 5)) +>Base01 : Symbol(Base01, Decl(genericDefaults.ts, 63, 37), Decl(genericDefaults.ts, 68, 13)) + +const Base01c01 = new Base01(1); +>Base01c01 : Symbol(Base01c01, Decl(genericDefaults.ts, 70, 5)) +>Base01 : Symbol(Base01, Decl(genericDefaults.ts, 63, 37), Decl(genericDefaults.ts, 68, 13)) + +const Base01c02 = new Base01(); +>Base01c02 : Symbol(Base01c02, Decl(genericDefaults.ts, 71, 5)) +>Base01 : Symbol(Base01, Decl(genericDefaults.ts, 63, 37), Decl(genericDefaults.ts, 68, 13)) + +const Base01c03 = new Base01(1); +>Base01c03 : Symbol(Base01c03, Decl(genericDefaults.ts, 72, 5)) +>Base01 : Symbol(Base01, Decl(genericDefaults.ts, 63, 37), Decl(genericDefaults.ts, 68, 13)) + +declare class Derived01 extends Base01 { } +>Derived01 : Symbol(Derived01, Decl(genericDefaults.ts, 72, 40)) +>T : Symbol(T, Decl(genericDefaults.ts, 74, 24)) +>Base01 : Symbol(Base01, Decl(genericDefaults.ts, 63, 37), Decl(genericDefaults.ts, 68, 13)) +>T : Symbol(T, Decl(genericDefaults.ts, 74, 24)) + +const Derived01c00 = new Derived01(); +>Derived01c00 : Symbol(Derived01c00, Decl(genericDefaults.ts, 75, 5)) +>Derived01 : Symbol(Derived01, Decl(genericDefaults.ts, 72, 40)) + +const Derived01c01 = new Derived01(1); +>Derived01c01 : Symbol(Derived01c01, Decl(genericDefaults.ts, 76, 5)) +>Derived01 : Symbol(Derived01, Decl(genericDefaults.ts, 72, 40)) + +const Derived01c02 = new Derived01(); +>Derived01c02 : Symbol(Derived01c02, Decl(genericDefaults.ts, 77, 5)) +>Derived01 : Symbol(Derived01, Decl(genericDefaults.ts, 72, 40)) + +const Derived01c03 = new Derived01(1); +>Derived01c03 : Symbol(Derived01c03, Decl(genericDefaults.ts, 78, 5)) +>Derived01 : Symbol(Derived01, Decl(genericDefaults.ts, 72, 40)) + +declare class Derived02 extends Base01 { } +>Derived02 : Symbol(Derived02, Decl(genericDefaults.ts, 78, 46)) +>T : Symbol(T, Decl(genericDefaults.ts, 80, 24)) +>Base01 : Symbol(Base01, Decl(genericDefaults.ts, 63, 37), Decl(genericDefaults.ts, 68, 13)) +>T : Symbol(T, Decl(genericDefaults.ts, 80, 24)) + +const Derived02c00 = new Derived02(); +>Derived02c00 : Symbol(Derived02c00, Decl(genericDefaults.ts, 81, 5)) +>Derived02 : Symbol(Derived02, Decl(genericDefaults.ts, 78, 46)) + +const Derived02c01 = new Derived02(1); +>Derived02c01 : Symbol(Derived02c01, Decl(genericDefaults.ts, 82, 5)) +>Derived02 : Symbol(Derived02, Decl(genericDefaults.ts, 78, 46)) + +const Derived02c02 = new Derived02(); +>Derived02c02 : Symbol(Derived02c02, Decl(genericDefaults.ts, 83, 5)) +>Derived02 : Symbol(Derived02, Decl(genericDefaults.ts, 78, 46)) + +const Derived02c03 = new Derived02(1); +>Derived02c03 : Symbol(Derived02c03, Decl(genericDefaults.ts, 84, 5)) +>Derived02 : Symbol(Derived02, Decl(genericDefaults.ts, 78, 46)) + diff --git a/tests/baselines/reference/genericDefaults.types b/tests/baselines/reference/genericDefaults.types new file mode 100644 index 00000000000..c693d4e4048 --- /dev/null +++ b/tests/baselines/reference/genericDefaults.types @@ -0,0 +1,500 @@ +=== tests/cases/compiler/genericDefaults.ts === +declare const x: any; +>x : any + +declare function f00(a?: T): T; +>f00 : (a?: T) => T +>T : T +>a : T +>T : T +>T : T + +const f00c00 = f00(); +>f00c00 : number +>f00() : number +>f00 : (a?: T) => T + +const f00c01 = f00(1); +>f00c01 : 1 +>f00(1) : 1 +>f00 : (a?: T) => T +>1 : 1 + +const f00c02 = f00("a"); +>f00c02 : "a" +>f00("a") : "a" +>f00 : (a?: T) => T +>"a" : "a" + +const f00c03 = f00(); +>f00c03 : number +>f00() : number +>f00 : (a?: T) => T + +const f00c04 = f00(1); +>f00c04 : number +>f00(1) : number +>f00 : (a?: T) => T +>1 : 1 + +const f00c05 = f00("a"); +>f00c05 : string +>f00("a") : string +>f00 : (a?: T) => T +>"a" : "a" + +declare function f01(a?: T, b?: U): [T, U]; +>f01 : (a?: T, b?: U) => [T, U] +>T : T +>U : U +>T : T +>a : T +>T : T +>b : U +>U : U +>T : T +>U : U + +const f01c00 = f01(); +>f01c00 : [{}, {}] +>f01() : [{}, {}] +>f01 : (a?: T, b?: U) => [T, U] + +const f01c01 = f01(1); +>f01c01 : [number, number] +>f01(1) : [number, number] +>f01 : (a?: T, b?: U) => [T, U] +>1 : 1 + +const f01c02 = f01(1, "a"); +>f01c02 : [number, string] +>f01(1, "a") : [number, string] +>f01 : (a?: T, b?: U) => [T, U] +>1 : 1 +>"a" : "a" + +const f01c03 = f01(); +>f01c03 : [number, number] +>f01() : [number, number] +>f01 : (a?: T, b?: U) => [T, U] + +const f01c04 = f01(1); +>f01c04 : [number, number] +>f01(1) : [number, number] +>f01 : (a?: T, b?: U) => [T, U] +>1 : 1 + +const f01c05 = f01(1, "a"); +>f01c05 : [number, string] +>f01(1, "a") : [number, string] +>f01 : (a?: T, b?: U) => [T, U] +>1 : 1 +>"a" : "a" + +const f01c06 = f01(); +>f01c06 : [number, string] +>f01() : [number, string] +>f01 : (a?: T, b?: U) => [T, U] + +const f01c07 = f01(1); +>f01c07 : [number, string] +>f01(1) : [number, string] +>f01 : (a?: T, b?: U) => [T, U] +>1 : 1 + +const f01c08 = f01(1, "a"); +>f01c08 : [number, string] +>f01(1, "a") : [number, string] +>f01 : (a?: T, b?: U) => [T, U] +>1 : 1 +>"a" : "a" + +declare function f02(a?: T, b?: U): [T, U]; +>f02 : (a?: T, b?: U) => [T, U] +>T : T +>U : U +>T : T +>a : T +>T : T +>b : U +>U : U +>T : T +>U : U + +const f02c00 = f02(); +>f02c00 : [number, number] +>f02() : [number, number] +>f02 : (a?: T, b?: U) => [T, U] + +const f02c01 = f02(1); +>f02c01 : [1, 1] +>f02(1) : [1, 1] +>f02 : (a?: T, b?: U) => [T, U] +>1 : 1 + +const f02c02 = f02(1, "a"); +>f02c02 : [1, string] +>f02(1, "a") : [1, string] +>f02 : (a?: T, b?: U) => [T, U] +>1 : 1 +>"a" : "a" + +const f02c03 = f02(); +>f02c03 : [number, number] +>f02() : [number, number] +>f02 : (a?: T, b?: U) => [T, U] + +const f02c04 = f02(1); +>f02c04 : [number, number] +>f02(1) : [number, number] +>f02 : (a?: T, b?: U) => [T, U] +>1 : 1 + +const f02c05 = f02(1, "a"); +>f02c05 : [number, string] +>f02(1, "a") : [number, string] +>f02 : (a?: T, b?: U) => [T, U] +>1 : 1 +>"a" : "a" + +const f02c06 = f02(); +>f02c06 : [number, string] +>f02() : [number, string] +>f02 : (a?: T, b?: U) => [T, U] + +const f02c07 = f02(1); +>f02c07 : [number, string] +>f02(1) : [number, string] +>f02 : (a?: T, b?: U) => [T, U] +>1 : 1 + +const f02c08 = f02(1, "a"); +>f02c08 : [number, string] +>f02(1, "a") : [number, string] +>f02 : (a?: T, b?: U) => [T, U] +>1 : 1 +>"a" : "a" + +declare function f03(a?: T, b?: U): [T, U]; +>f03 : (a?: T, b?: U) => [T, U] +>T : T +>U : U +>T : T +>T : T +>a : T +>T : T +>b : U +>U : U +>T : T +>U : U + +const f03c00 = f03(); +>f03c00 : [number, number] +>f03() : [number, number] +>f03 : (a?: T, b?: U) => [T, U] + +const f03c01 = f03(1); +>f03c01 : [1, 1] +>f03(1) : [1, 1] +>f03 : (a?: T, b?: U) => [T, U] +>1 : 1 + +const f03c02 = f03(1, 1); +>f03c02 : [1, 1] +>f03(1, 1) : [1, 1] +>f03 : (a?: T, b?: U) => [T, U] +>1 : 1 +>1 : 1 + +const f03c03 = f03(); +>f03c03 : [number, number] +>f03() : [number, number] +>f03 : (a?: T, b?: U) => [T, U] + +const f03c04 = f03(1); +>f03c04 : [number, number] +>f03(1) : [number, number] +>f03 : (a?: T, b?: U) => [T, U] +>1 : 1 + +const f03c05 = f03(1, 2); +>f03c05 : [number, number] +>f03(1, 2) : [number, number] +>f03 : (a?: T, b?: U) => [T, U] +>1 : 1 +>2 : 2 + +const f03c06 = f03(); +>f03c06 : [number, number] +>f03() : [number, number] +>f03 : (a?: T, b?: U) => [T, U] + +const f03c07 = f03(1); +>f03c07 : [number, number] +>f03(1) : [number, number] +>f03 : (a?: T, b?: U) => [T, U] +>1 : 1 + +const f03c08 = f03(1, 2); +>f03c08 : [number, number] +>f03(1, 2) : [number, number] +>f03 : (a?: T, b?: U) => [T, U] +>1 : 1 +>2 : 2 + +interface i00 { a: T; } +>i00 : i00 +>T : T +>a : T +>T : T + +const i00c00 = (x).a; +>i00c00 : number +>(x).a : number +>(x) : i00 +>x : i00 +>i00 : i00 +>x : any +>a : number + +const i00c01 = (>x).a; +>i00c01 : number +>(>x).a : number +>(>x) : i00 +>>x : i00 +>i00 : i00 +>x : any +>a : number + +interface i01 { a: [T, U]; } +>i01 : i01 +>T : T +>U : U +>T : T +>a : [T, U] +>T : T +>U : U + +const i01c00 = (>x).a; +>i01c00 : [number, number] +>(>x).a : [number, number] +>(>x) : i01 +>>x : i01 +>i01 : i01 +>x : any +>a : [number, number] + +const i01c01 = (>x).a; +>i01c01 : [number, string] +>(>x).a : [number, string] +>(>x) : i01 +>>x : i01 +>i01 : i01 +>x : any +>a : [number, string] + +interface i02 { a: [T, U]; } +>i02 : i02 +>T : T +>U : U +>T : T +>a : [T, U] +>T : T +>U : U + +const i02c00 = (>x).a; +>i02c00 : [number, number] +>(>x).a : [number, number] +>(>x) : i02 +>>x : i02 +>i02 : i02 +>x : any +>a : [number, number] + +const i02c01 = (>x).a; +>i02c01 : [1, 1] +>(>x).a : [1, 1] +>(>x) : i02<1, 1> +>>x : i02<1, 1> +>i02 : i02 +>x : any +>a : [1, 1] + +const i02c02 = (>x).a; +>i02c02 : [number, number] +>(>x).a : [number, number] +>(>x) : i02 +>>x : i02 +>i02 : i02 +>x : any +>a : [number, number] + +const i02c03 = (>x).a; +>i02c03 : [1, number] +>(>x).a : [1, number] +>(>x) : i02<1, number> +>>x : i02<1, number> +>i02 : i02 +>x : any +>a : [1, number] + +const i02c04 = (>x).a; +>i02c04 : [number, 1] +>(>x).a : [number, 1] +>(>x) : i02 +>>x : i02 +>i02 : i02 +>x : any +>a : [number, 1] + +interface i03 { a: [T, U]; } +>i03 : i03 +>T : T +>U : U +>T : T +>T : T +>a : [T, U] +>T : T +>U : U + +const i03c00 = (>x).a; +>i03c00 : [number, number] +>(>x).a : [number, number] +>(>x) : i03 +>>x : i03 +>i03 : i03 +>x : any +>a : [number, number] + +const i03c01 = (>x).a; +>i03c01 : [1, 1] +>(>x).a : [1, 1] +>(>x) : i03<1, 1> +>>x : i03<1, 1> +>i03 : i03 +>x : any +>a : [1, 1] + +const i03c02 = (>x).a; +>i03c02 : [number, number] +>(>x).a : [number, number] +>(>x) : i03 +>>x : i03 +>i03 : i03 +>x : any +>a : [number, number] + +const i03c03 = (>x).a; +>i03c03 : [1, 1] +>(>x).a : [1, 1] +>(>x) : i03<1, 1> +>>x : i03<1, 1> +>i03 : i03 +>x : any +>a : [1, 1] + +const i03c04 = (>x).a; +>i03c04 : [number, 1] +>(>x).a : [number, 1] +>(>x) : i03 +>>x : i03 +>i03 : i03 +>x : any +>a : [number, 1] + +interface Base01 { a: T; } +>Base01 : Base01 +>T : T +>a : T +>T : T + +interface Base01Constructor { new (a?: T): Base01; } +>Base01Constructor : Base01Constructor +>T : T +>a : T +>T : T +>Base01 : Base01 +>T : T + +declare const Base01: Base01Constructor; +>Base01 : Base01Constructor +>Base01Constructor : Base01Constructor + +const Base01c00 = new Base01(); +>Base01c00 : Base01 +>new Base01() : Base01 +>Base01 : Base01Constructor + +const Base01c01 = new Base01(1); +>Base01c01 : Base01 +>new Base01(1) : Base01 +>Base01 : Base01Constructor +>1 : 1 + +const Base01c02 = new Base01(); +>Base01c02 : Base01 +>new Base01() : Base01 +>Base01 : Base01Constructor + +const Base01c03 = new Base01(1); +>Base01c03 : Base01 +>new Base01(1) : Base01 +>Base01 : Base01Constructor +>1 : 1 + +declare class Derived01 extends Base01 { } +>Derived01 : Derived01 +>T : T +>Base01 : Base01 +>T : T + +const Derived01c00 = new Derived01(); +>Derived01c00 : Derived01<{}> +>new Derived01() : Derived01<{}> +>Derived01 : typeof Derived01 + +const Derived01c01 = new Derived01(1); +>Derived01c01 : Derived01 +>new Derived01(1) : Derived01 +>Derived01 : typeof Derived01 +>1 : 1 + +const Derived01c02 = new Derived01(); +>Derived01c02 : Derived01 +>new Derived01() : Derived01 +>Derived01 : typeof Derived01 + +const Derived01c03 = new Derived01(1); +>Derived01c03 : Derived01 +>new Derived01(1) : Derived01 +>Derived01 : typeof Derived01 +>1 : 1 + +declare class Derived02 extends Base01 { } +>Derived02 : Derived02 +>T : T +>Base01 : Base01 +>T : T + +const Derived02c00 = new Derived02(); +>Derived02c00 : Derived02 +>new Derived02() : Derived02 +>Derived02 : typeof Derived02 + +const Derived02c01 = new Derived02(1); +>Derived02c01 : Derived02 +>new Derived02(1) : Derived02 +>Derived02 : typeof Derived02 +>1 : 1 + +const Derived02c02 = new Derived02(); +>Derived02c02 : Derived02 +>new Derived02() : Derived02 +>Derived02 : typeof Derived02 + +const Derived02c03 = new Derived02(1); +>Derived02c03 : Derived02 +>new Derived02(1) : Derived02 +>Derived02 : typeof Derived02 +>1 : 1 + diff --git a/tests/baselines/reference/genericDefaultsErrors.errors.txt b/tests/baselines/reference/genericDefaultsErrors.errors.txt new file mode 100644 index 00000000000..5e19e25f270 --- /dev/null +++ b/tests/baselines/reference/genericDefaultsErrors.errors.txt @@ -0,0 +1,114 @@ +tests/cases/compiler/genericDefaultsErrors.ts(4,26): error TS2706: Type parameter 'T' has a circular default. +tests/cases/compiler/genericDefaultsErrors.ts(5,26): error TS2706: Type parameter 'T' has a circular default. +tests/cases/compiler/genericDefaultsErrors.ts(5,33): error TS2706: Type parameter 'U' has a circular default. +tests/cases/compiler/genericDefaultsErrors.ts(6,29): error TS2705: Required type parameters may not follow optional type parameters +tests/cases/compiler/genericDefaultsErrors.ts(7,41): error TS2344: Type 'number' does not satisfy the constraint 'string'. +tests/cases/compiler/genericDefaultsErrors.ts(8,59): error TS2344: Type 'T' does not satisfy the constraint 'number'. + Type 'string' is not assignable to type 'number'. +tests/cases/compiler/genericDefaultsErrors.ts(9,44): error TS2344: Type 'T' does not satisfy the constraint 'number'. +tests/cases/compiler/genericDefaultsErrors.ts(10,39): error TS2344: Type 'number' does not satisfy the constraint 'T'. +tests/cases/compiler/genericDefaultsErrors.ts(14,1): error TS2346: Supplied parameters do not match any signature of call target. +tests/cases/compiler/genericDefaultsErrors.ts(17,1): error TS2346: Supplied parameters do not match any signature of call target. +tests/cases/compiler/genericDefaultsErrors.ts(20,11): error TS2428: All declarations of 'i00' must have identical type parameters. +tests/cases/compiler/genericDefaultsErrors.ts(23,11): error TS2428: All declarations of 'i01' must have identical type parameters. +tests/cases/compiler/genericDefaultsErrors.ts(25,19): error TS2706: Type parameter 'T' has a circular default. +tests/cases/compiler/genericDefaultsErrors.ts(26,19): error TS2706: Type parameter 'T' has a circular default. +tests/cases/compiler/genericDefaultsErrors.ts(26,26): error TS2706: Type parameter 'U' has a circular default. +tests/cases/compiler/genericDefaultsErrors.ts(27,22): error TS2705: Required type parameters may not follow optional type parameters +tests/cases/compiler/genericDefaultsErrors.ts(28,34): error TS2344: Type 'number' does not satisfy the constraint 'string'. +tests/cases/compiler/genericDefaultsErrors.ts(29,52): error TS2344: Type 'T' does not satisfy the constraint 'number'. + Type 'string' is not assignable to type 'number'. +tests/cases/compiler/genericDefaultsErrors.ts(30,37): error TS2344: Type 'T' does not satisfy the constraint 'number'. +tests/cases/compiler/genericDefaultsErrors.ts(31,32): error TS2344: Type 'number' does not satisfy the constraint 'T'. +tests/cases/compiler/genericDefaultsErrors.ts(34,15): error TS2707: Generic type 'i09' requires between 2 and 3 type arguments +tests/cases/compiler/genericDefaultsErrors.ts(35,15): error TS2707: Generic type 'i09' requires between 2 and 3 type arguments +tests/cases/compiler/genericDefaultsErrors.ts(38,15): error TS2707: Generic type 'i09' requires between 2 and 3 type arguments + + +==== tests/cases/compiler/genericDefaultsErrors.ts (23 errors) ==== + + declare const x: any; + + declare function f00(): void; + ~ +!!! error TS2706: Type parameter 'T' has a circular default. + declare function f01(): void; + ~ +!!! error TS2706: Type parameter 'T' has a circular default. + ~ +!!! error TS2706: Type parameter 'U' has a circular default. + declare function f02(); + ~ +!!! error TS2705: Required type parameters may not follow optional type parameters + declare function f03(): void; + ~~~~~~ +!!! error TS2344: Type 'number' does not satisfy the constraint 'string'. + declare function f04(): void; + ~ +!!! error TS2344: Type 'T' does not satisfy the constraint 'number'. +!!! error TS2344: Type 'string' is not assignable to type 'number'. + declare function f05(): void; + ~ +!!! error TS2344: Type 'T' does not satisfy the constraint 'number'. + declare function f06(): void; + ~~~~~~ +!!! error TS2344: Type 'number' does not satisfy the constraint 'T'. + + declare function f07(): void; + f07(); // ok + f07<1>(); // error + ~~~~~~~~ +!!! error TS2346: Supplied parameters do not match any signature of call target. + f07<1, 2>(); // ok + f07<1, 2, 3>(); // ok + f07<1, 2, 3, 4>(); // error + ~~~~~~~~~~~~~~~~~ +!!! error TS2346: Supplied parameters do not match any signature of call target. + + interface i00 { } + interface i00 { } + ~~~ +!!! error TS2428: All declarations of 'i00' must have identical type parameters. + + interface i01 { } + interface i01 { } + ~~~ +!!! error TS2428: All declarations of 'i01' must have identical type parameters. + + interface i02 { } + ~ +!!! error TS2706: Type parameter 'T' has a circular default. + interface i03 { } + ~ +!!! error TS2706: Type parameter 'T' has a circular default. + ~ +!!! error TS2706: Type parameter 'U' has a circular default. + interface i04 { } + ~ +!!! error TS2705: Required type parameters may not follow optional type parameters + interface i05 { } + ~~~~~~ +!!! error TS2344: Type 'number' does not satisfy the constraint 'string'. + interface i06 { } + ~ +!!! error TS2344: Type 'T' does not satisfy the constraint 'number'. +!!! error TS2344: Type 'string' is not assignable to type 'number'. + interface i07 { } + ~ +!!! error TS2344: Type 'T' does not satisfy the constraint 'number'. + interface i08 { } + ~~~~~~ +!!! error TS2344: Type 'number' does not satisfy the constraint 'T'. + + interface i09 { } + type i09t00 = i09; // error + ~~~ +!!! error TS2707: Generic type 'i09' requires between 2 and 3 type arguments + type i09t01 = i09<1>; // error + ~~~~~~ +!!! error TS2707: Generic type 'i09' requires between 2 and 3 type arguments + type i09t02 = i09<1, 2>; // ok + type i09t03 = i09<1, 2, 3>; // ok + type i09t04 = i09<1, 2, 3, 4>; // error + ~~~~~~~~~~~~~~~ +!!! error TS2707: Generic type 'i09' requires between 2 and 3 type arguments \ No newline at end of file diff --git a/tests/baselines/reference/genericDefaultsErrors.js b/tests/baselines/reference/genericDefaultsErrors.js new file mode 100644 index 00000000000..9615ad2e362 --- /dev/null +++ b/tests/baselines/reference/genericDefaultsErrors.js @@ -0,0 +1,87 @@ +//// [genericDefaultsErrors.ts] + +declare const x: any; + +declare function f00(): void; +declare function f01(): void; +declare function f02(); +declare function f03(): void; +declare function f04(): void; +declare function f05(): void; +declare function f06(): void; + +declare function f07(): void; +f07(); // ok +f07<1>(); // error +f07<1, 2>(); // ok +f07<1, 2, 3>(); // ok +f07<1, 2, 3, 4>(); // error + +interface i00 { } +interface i00 { } + +interface i01 { } +interface i01 { } + +interface i02 { } +interface i03 { } +interface i04 { } +interface i05 { } +interface i06 { } +interface i07 { } +interface i08 { } + +interface i09 { } +type i09t00 = i09; // error +type i09t01 = i09<1>; // error +type i09t02 = i09<1, 2>; // ok +type i09t03 = i09<1, 2, 3>; // ok +type i09t04 = i09<1, 2, 3, 4>; // error + +//// [genericDefaultsErrors.js] +f07(); // ok +f07(); // error +f07(); // ok +f07(); // ok +f07(); // error + + +//// [genericDefaultsErrors.d.ts] +declare const x: any; +declare function f00(): void; +declare function f01(): void; +declare function f02(): any; +declare function f03(): void; +declare function f04(): void; +declare function f05(): void; +declare function f06(): void; +declare function f07(): void; +interface i00 { +} +interface i00 { +} +interface i01 { +} +interface i01 { +} +interface i02 { +} +interface i03 { +} +interface i04 { +} +interface i05 { +} +interface i06 { +} +interface i07 { +} +interface i08 { +} +interface i09 { +} +declare type i09t00 = i09; +declare type i09t01 = i09<1>; +declare type i09t02 = i09<1, 2>; +declare type i09t03 = i09<1, 2, 3>; +declare type i09t04 = i09<1, 2, 3, 4>; diff --git a/tests/cases/compiler/genericDefaults.ts b/tests/cases/compiler/genericDefaults.ts new file mode 100644 index 00000000000..9ab0ede05b6 --- /dev/null +++ b/tests/cases/compiler/genericDefaults.ts @@ -0,0 +1,86 @@ +// @declaration: true +declare const x: any; + +declare function f00(a?: T): T; +const f00c00 = f00(); +const f00c01 = f00(1); +const f00c02 = f00("a"); +const f00c03 = f00(); +const f00c04 = f00(1); +const f00c05 = f00("a"); + +declare function f01(a?: T, b?: U): [T, U]; +const f01c00 = f01(); +const f01c01 = f01(1); +const f01c02 = f01(1, "a"); +const f01c03 = f01(); +const f01c04 = f01(1); +const f01c05 = f01(1, "a"); +const f01c06 = f01(); +const f01c07 = f01(1); +const f01c08 = f01(1, "a"); + +declare function f02(a?: T, b?: U): [T, U]; +const f02c00 = f02(); +const f02c01 = f02(1); +const f02c02 = f02(1, "a"); +const f02c03 = f02(); +const f02c04 = f02(1); +const f02c05 = f02(1, "a"); +const f02c06 = f02(); +const f02c07 = f02(1); +const f02c08 = f02(1, "a"); + +declare function f03(a?: T, b?: U): [T, U]; +const f03c00 = f03(); +const f03c01 = f03(1); +const f03c02 = f03(1, 1); +const f03c03 = f03(); +const f03c04 = f03(1); +const f03c05 = f03(1, 2); +const f03c06 = f03(); +const f03c07 = f03(1); +const f03c08 = f03(1, 2); + +interface i00 { a: T; } +const i00c00 = (x).a; +const i00c01 = (>x).a; + +interface i01 { a: [T, U]; } +const i01c00 = (>x).a; +const i01c01 = (>x).a; + +interface i02 { a: [T, U]; } +const i02c00 = (>x).a; +const i02c01 = (>x).a; +const i02c02 = (>x).a; +const i02c03 = (>x).a; +const i02c04 = (>x).a; + +interface i03 { a: [T, U]; } +const i03c00 = (>x).a; +const i03c01 = (>x).a; +const i03c02 = (>x).a; +const i03c03 = (>x).a; +const i03c04 = (>x).a; + +interface Base01 { a: T; } +interface Base01Constructor { new (a?: T): Base01; } + +declare const Base01: Base01Constructor; +const Base01c00 = new Base01(); +const Base01c01 = new Base01(1); +const Base01c02 = new Base01(); +const Base01c03 = new Base01(1); + +declare class Derived01 extends Base01 { } +const Derived01c00 = new Derived01(); +const Derived01c01 = new Derived01(1); +const Derived01c02 = new Derived01(); +const Derived01c03 = new Derived01(1); + +declare class Derived02 extends Base01 { } +const Derived02c00 = new Derived02(); +const Derived02c01 = new Derived02(1); +const Derived02c02 = new Derived02(); +const Derived02c03 = new Derived02(1); diff --git a/tests/cases/compiler/genericDefaultsErrors.ts b/tests/cases/compiler/genericDefaultsErrors.ts new file mode 100644 index 00000000000..470b4998e92 --- /dev/null +++ b/tests/cases/compiler/genericDefaultsErrors.ts @@ -0,0 +1,39 @@ +// @declaration: true + +declare const x: any; + +declare function f00(): void; +declare function f01(): void; +declare function f02(); +declare function f03(): void; +declare function f04(): void; +declare function f05(): void; +declare function f06(): void; + +declare function f07(): void; +f07(); // ok +f07<1>(); // error +f07<1, 2>(); // ok +f07<1, 2, 3>(); // ok +f07<1, 2, 3, 4>(); // error + +interface i00 { } +interface i00 { } + +interface i01 { } +interface i01 { } + +interface i02 { } +interface i03 { } +interface i04 { } +interface i05 { } +interface i06 { } +interface i07 { } +interface i08 { } + +interface i09 { } +type i09t00 = i09; // error +type i09t01 = i09<1>; // error +type i09t02 = i09<1, 2>; // ok +type i09t03 = i09<1, 2, 3>; // ok +type i09t04 = i09<1, 2, 3, 4>; // error \ No newline at end of file