@@ -4840,15 +4840,60 @@ namespace ts {
48404840 }
48414841 }
48424842
4843- function getDefaultOfTypeParameter(typeParameter: TypeParameter): Type {
4843+ /**
4844+ * Gets the default type for a type parameter.
4845+ *
4846+ * If the type parameter is the result of an instantiation, this gets the instantiated
4847+ * default type of its target. If the type parameter has no default type, `undefined`
4848+ * is returned.
4849+ *
4850+ * This function *does not* perform a circularity check.
4851+ */
4852+ function getDefaultFromTypeParameter(typeParameter: TypeParameter): Type | undefined {
4853+ if (!typeParameter.default) {
4854+ if (typeParameter.target) {
4855+ const targetDefault = getDefaultFromTypeParameter(typeParameter.target);
4856+ typeParameter.default = targetDefault ? instantiateType(targetDefault, typeParameter.mapper) : noConstraintOrDefaultType;
4857+ }
4858+ else {
4859+ const defaultDeclaration = typeParameter.symbol && forEach(typeParameter.symbol.declarations, decl => isTypeParameter(decl) && decl.default);
4860+ typeParameter.default = defaultDeclaration ? getTypeFromTypeNode(defaultDeclaration) : noConstraintOrDefaultType;
4861+ }
4862+ }
4863+ return typeParameter.default === noConstraintOrDefaultType ? undefined : typeParameter.default;
4864+ }
4865+
4866+ /**
4867+ * Gets the default type for a type parameter.
4868+ *
4869+ * If the type parameter is the result of an instantiation, this gets the instantiated
4870+ * default type of its target. If the type parameter has no default type, or if the default
4871+ * type circularly references the type parameter, `undefined` is returned.
4872+ *
4873+ * This function *does* perform a circularity check.
4874+ */
4875+ function getDefaultOfTypeParameter(typeParameter: TypeParameter): Type | undefined {
48444876 return hasNonCircularDefault(typeParameter) ? getDefaultFromTypeParameter(typeParameter) : undefined;
48454877 }
48464878
4847- function hasNonCircularDefault(type: TypeParameter) {
4848- return getResolvedDefault(type) !== circularConstraintOrDefaultType;
4879+ /**
4880+ * Determines whether a type parameter has a non-circular default type.
4881+ *
4882+ * Note that this function also returns `true` if a type parameter *does not* have a
4883+ * default type.
4884+ */
4885+ function hasNonCircularDefault(typeParameter: TypeParameter): boolean {
4886+ return getResolvedDefault(typeParameter) !== circularConstraintOrDefaultType;
48494887 }
48504888
4851- function getResolvedDefault(typeParameter: TypeParameter) {
4889+ /**
4890+ * Resolves the default type of a type parameter.
4891+ *
4892+ * If the type parameter has no default, the `noConstraintOrDefaultType` singleton is
4893+ * returned. If the type parameter has a circular default, the
4894+ * `circularConstraintOrDefaultType` singleton is returned.
4895+ */
4896+ function getResolvedDefault(typeParameter: TypeParameter): Type {
48524897 if (!typeParameter.resolvedDefault) {
48534898 if (!pushTypeResolution(typeParameter, TypeSystemPropertyName.ResolvedDefault)) {
48544899 return circularConstraintOrDefaultType;
@@ -4863,6 +4908,12 @@ namespace ts {
48634908 return typeParameter.resolvedDefault;
48644909 }
48654910
4911+ /**
4912+ * Recursively resolves the default type for a type.
4913+ *
4914+ * If the type is a union or intersection type and any of its constituents is a circular
4915+ * reference, the `circularConstraintOrDefaultType` singleton is returned.
4916+ */
48664917 function getResolvedDefaultWorker(type: Type): Type {
48674918 if (type.flags & TypeFlags.TypeParameter) {
48684919 return getResolvedDefault(<TypeParameter>type);
@@ -5173,6 +5224,14 @@ namespace ts {
51735224 return minTypeArgumentCount;
51745225 }
51755226
5227+ /**
5228+ * Fill in default types for unsupplied type arguments. If `typeArguments` is undefined
5229+ * when a default type is supplied, a new array will be created and returned.
5230+ *
5231+ * @param typeArguments The supplied type arguments.
5232+ * @param typeParameters The requested type parameters.
5233+ * @param minTypeArgumentCount The minimum number of required type arguments.
5234+ */
51765235 function fillMissingTypeArguments(typeArguments: Type[] | undefined, typeParameters: TypeParameter[] | undefined, minTypeArgumentCount: number) {
51775236 const numTypeParameters = typeParameters ? typeParameters.length : 0;
51785237 if (numTypeParameters) {
@@ -5488,20 +5547,6 @@ namespace ts {
54885547 return typeParameter.constraint === noConstraintOrDefaultType ? undefined : typeParameter.constraint;
54895548 }
54905549
5491- function getDefaultFromTypeParameter(typeParameter: TypeParameter): Type | undefined {
5492- if (!typeParameter.default) {
5493- if (typeParameter.target) {
5494- const targetDefault = getDefaultFromTypeParameter(typeParameter.target);
5495- typeParameter.default = targetDefault ? instantiateType(targetDefault, typeParameter.mapper) : noConstraintOrDefaultType;
5496- }
5497- else {
5498- const defaultDeclaration = typeParameter.symbol && forEach(typeParameter.symbol.declarations, decl => isTypeParameter(decl) && decl.default);
5499- typeParameter.default = defaultDeclaration ? getTypeFromTypeNode(defaultDeclaration) : noConstraintOrDefaultType;
5500- }
5501- }
5502- return typeParameter.default === noConstraintOrDefaultType ? undefined : typeParameter.default;
5503- }
5504-
55055550 function getParentSymbolOfTypeParameter(typeParameter: TypeParameter): Symbol {
55065551 return getSymbolOfNode(getDeclarationOfKind(typeParameter.symbol, SyntaxKind.TypeParameter).parent);
55075552 }
@@ -13535,6 +13580,7 @@ namespace ts {
1353513580 ? createInferenceContext(originalCandidate, /*inferUnionTypes*/ false)
1353613581 : undefined;
1353713582
13583+ // fix each supplied type argument in the inference context
1353813584 if (typeArguments) {
1353913585 for (let i = 0; i < typeArguments.length; i++) {
1354013586 inferenceContext.inferredTypes[i] = getTypeFromTypeNode(typeArguments[i]);
@@ -13545,8 +13591,10 @@ namespace ts {
1354513591 while (true) {
1354613592 candidate = originalCandidate;
1354713593 if (candidate.typeParameters) {
13548- typeArgumentsAreValid = typeArguments ? checkTypeArguments(candidate, typeArguments, inferenceContext.inferredTypes, /*reportErrors*/ false) : true;
13594+ // Check any supplied type arguments against the candidate.
13595+ typeArgumentsAreValid = !typeArguments || checkTypeArguments(candidate, typeArguments, inferenceContext.inferredTypes, /*reportErrors*/ false);
1354913596 if (typeArgumentsAreValid) {
13597+ // Infer any unsupplied type arguments for the candidate.
1355013598 inferTypeArguments(node, candidate, args, excludeArgument, inferenceContext);
1355113599 typeArgumentsAreValid = inferenceContext.failedTypeParameterIndex === undefined;
1355213600 }
0 commit comments