@@ -4840,15 +4840,60 @@ namespace ts {
4840
4840
}
4841
4841
}
4842
4842
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 {
4844
4876
return hasNonCircularDefault(typeParameter) ? getDefaultFromTypeParameter(typeParameter) : undefined;
4845
4877
}
4846
4878
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;
4849
4887
}
4850
4888
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 {
4852
4897
if (!typeParameter.resolvedDefault) {
4853
4898
if (!pushTypeResolution(typeParameter, TypeSystemPropertyName.ResolvedDefault)) {
4854
4899
return circularConstraintOrDefaultType;
@@ -4863,6 +4908,12 @@ namespace ts {
4863
4908
return typeParameter.resolvedDefault;
4864
4909
}
4865
4910
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
+ */
4866
4917
function getResolvedDefaultWorker(type: Type): Type {
4867
4918
if (type.flags & TypeFlags.TypeParameter) {
4868
4919
return getResolvedDefault(<TypeParameter>type);
@@ -5173,6 +5224,14 @@ namespace ts {
5173
5224
return minTypeArgumentCount;
5174
5225
}
5175
5226
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
+ */
5176
5235
function fillMissingTypeArguments(typeArguments: Type[] | undefined, typeParameters: TypeParameter[] | undefined, minTypeArgumentCount: number) {
5177
5236
const numTypeParameters = typeParameters ? typeParameters.length : 0;
5178
5237
if (numTypeParameters) {
@@ -5488,20 +5547,6 @@ namespace ts {
5488
5547
return typeParameter.constraint === noConstraintOrDefaultType ? undefined : typeParameter.constraint;
5489
5548
}
5490
5549
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
-
5505
5550
function getParentSymbolOfTypeParameter(typeParameter: TypeParameter): Symbol {
5506
5551
return getSymbolOfNode(getDeclarationOfKind(typeParameter.symbol, SyntaxKind.TypeParameter).parent);
5507
5552
}
@@ -13535,6 +13580,7 @@ namespace ts {
13535
13580
? createInferenceContext(originalCandidate, /*inferUnionTypes*/ false)
13536
13581
: undefined;
13537
13582
13583
+ // fix each supplied type argument in the inference context
13538
13584
if (typeArguments) {
13539
13585
for (let i = 0; i < typeArguments.length; i++) {
13540
13586
inferenceContext.inferredTypes[i] = getTypeFromTypeNode(typeArguments[i]);
@@ -13545,8 +13591,10 @@ namespace ts {
13545
13591
while (true) {
13546
13592
candidate = originalCandidate;
13547
13593
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);
13549
13596
if (typeArgumentsAreValid) {
13597
+ // Infer any unsupplied type arguments for the candidate.
13550
13598
inferTypeArguments(node, candidate, args, excludeArgument, inferenceContext);
13551
13599
typeArgumentsAreValid = inferenceContext.failedTypeParameterIndex === undefined;
13552
13600
}
0 commit comments