@@ -3973,7 +3973,7 @@ namespace ts {
39733973 return true;
39743974 }
39753975 if (type.flags & TypeFlags.TypeVariable) {
3976- const constraint = getBaseConstraintOfType(<TypeVariable> type);
3976+ const constraint = getBaseConstraintOfType(type);
39773977 return constraint && isValidBaseType(constraint) && isMixinConstructorType(constraint);
39783978 }
39793979 return false;
@@ -4989,16 +4989,32 @@ namespace ts {
49894989 }
49904990
49914991 function getConstraintOfType(type: TypeVariable | UnionOrIntersectionType): Type {
4992- return type.flags & TypeFlags.TypeParameter ? getConstraintOfTypeParameter(<TypeParameter>type) : getBaseConstraintOfType(type);
4992+ return type.flags & TypeFlags.TypeParameter ? getConstraintOfTypeParameter(<TypeParameter>type) :
4993+ type.flags & TypeFlags.IndexedAccess ? getConstraintOfIndexedAccess(<IndexedAccessType>type) :
4994+ getBaseConstraintOfType(type);
49934995 }
49944996
49954997 function getConstraintOfTypeParameter(typeParameter: TypeParameter): Type {
49964998 return hasNonCircularBaseConstraint(typeParameter) ? getConstraintFromTypeParameter(typeParameter) : undefined;
49974999 }
49985000
4999- function getBaseConstraintOfType(type: TypeVariable | UnionOrIntersectionType): Type {
5000- const constraint = getResolvedBaseConstraint(type);
5001- return constraint !== noConstraintType && constraint !== circularConstraintType ? constraint : undefined;
5001+ function getConstraintOfIndexedAccess(type: IndexedAccessType) {
5002+ const baseObjectType = getBaseConstraintOfType(type.objectType);
5003+ const baseIndexType = getBaseConstraintOfType(type.indexType);
5004+ return baseObjectType || baseIndexType ? getIndexedAccessType(baseObjectType || type.objectType, baseIndexType || type.indexType) : undefined;
5005+ }
5006+
5007+ function getBaseConstraintOfType(type: Type): Type {
5008+ if (type.flags & (TypeFlags.TypeVariable | TypeFlags.UnionOrIntersection)) {
5009+ const constraint = getResolvedBaseConstraint(<TypeVariable | UnionOrIntersectionType>type);
5010+ if (constraint !== noConstraintType && constraint !== circularConstraintType) {
5011+ return constraint;
5012+ }
5013+ }
5014+ else if (type.flags & TypeFlags.Index) {
5015+ return stringType;
5016+ }
5017+ return undefined;
50025018 }
50035019
50045020 function hasNonCircularBaseConstraint(type: TypeVariable): boolean {
@@ -5096,7 +5112,7 @@ namespace ts {
50965112 * type itself. Note that the apparent type of a union type is the union type itself.
50975113 */
50985114 function getApparentType(type: Type): Type {
5099- const t = type.flags & TypeFlags.TypeVariable ? getBaseConstraintOfType(<TypeVariable> type) || emptyObjectType : type;
5115+ const t = type.flags & TypeFlags.TypeVariable ? getBaseConstraintOfType(type) || emptyObjectType : type;
51005116 return t.flags & TypeFlags.Intersection ? getApparentTypeOfIntersectionType(<IntersectionType>t) :
51015117 t.flags & TypeFlags.StringLike ? globalStringType :
51025118 t.flags & TypeFlags.NumberLike ? globalNumberType :
@@ -7921,7 +7937,7 @@ namespace ts {
79217937 }
79227938 // A type S is related to a type T[K] if S is related to A[K], where K is string-like and
79237939 // A is the apparent type of S.
7924- const constraint = getBaseConstraintOfType(<IndexedAccessType> target);
7940+ const constraint = getBaseConstraintOfType(target);
79257941 if (constraint) {
79267942 if (result = isRelatedTo(source, constraint, reportErrors)) {
79277943 errorInfo = saveErrorInfo;
@@ -7961,7 +7977,7 @@ namespace ts {
79617977 else if (source.flags & TypeFlags.IndexedAccess) {
79627978 // A type S[K] is related to a type T if A[K] is related to T, where K is string-like and
79637979 // A is the apparent type of S.
7964- const constraint = getBaseConstraintOfType (<IndexedAccessType>source);
7980+ const constraint = getConstraintOfType (<IndexedAccessType>source);
79657981 if (constraint) {
79667982 if (result = isRelatedTo(constraint, target, reportErrors)) {
79677983 errorInfo = saveErrorInfo;
@@ -9184,13 +9200,14 @@ namespace ts {
91849200 }
91859201 }
91869202
9187- function createInferenceContext(signature: Signature, inferUnionTypes: boolean): InferenceContext {
9203+ function createInferenceContext(signature: Signature, inferUnionTypes: boolean, useAnyForNoInferences: boolean ): InferenceContext {
91889204 const inferences = map(signature.typeParameters, createTypeInferencesObject);
91899205 return {
91909206 signature,
91919207 inferUnionTypes,
91929208 inferences,
91939209 inferredTypes: new Array(signature.typeParameters.length),
9210+ useAnyForNoInferences
91949211 };
91959212 }
91969213
@@ -9604,7 +9621,7 @@ namespace ts {
96049621 getInferenceMapper(context)));
96059622 }
96069623 else {
9607- inferredType = emptyObjectType;
9624+ inferredType = context.useAnyForNoInferences ? anyType : emptyObjectType;
96089625 }
96099626
96109627 inferenceSucceeded = true;
@@ -9873,7 +9890,7 @@ namespace ts {
98739890 return strictNullChecks ? TypeFacts.ObjectStrictFacts : TypeFacts.ObjectFacts;
98749891 }
98759892 if (flags & TypeFlags.TypeVariable) {
9876- return getTypeFacts(getBaseConstraintOfType(<TypeVariable> type) || emptyObjectType);
9893+ return getTypeFacts(getBaseConstraintOfType(type) || emptyObjectType);
98779894 }
98789895 if (flags & TypeFlags.UnionOrIntersection) {
98799896 return getTypeFactsOfTypes((<UnionOrIntersectionType>type).types);
@@ -10685,7 +10702,7 @@ namespace ts {
1068510702 return targetType;
1068610703 }
1068710704 if (type.flags & TypeFlags.TypeVariable) {
10688- const constraint = getBaseConstraintOfType(<TypeVariable> type) || anyType;
10705+ const constraint = getBaseConstraintOfType(type) || anyType;
1068910706 if (isTypeSubtypeOf(targetType, constraint)) {
1069010707 return getIntersectionType([type, targetType]);
1069110708 }
@@ -13652,7 +13669,7 @@ namespace ts {
1365213669
1365313670 // Instantiate a generic signature in the context of a non-generic signature (section 3.8.5 in TypeScript spec)
1365413671 function instantiateSignatureInContextOf(signature: Signature, contextualSignature: Signature, contextualMapper: TypeMapper): Signature {
13655- const context = createInferenceContext(signature, /*inferUnionTypes*/ true);
13672+ const context = createInferenceContext(signature, /*inferUnionTypes*/ true, /*useAnyForNoInferences*/ false );
1365613673 forEachMatchingParameterType(contextualSignature, signature, (source, target) => {
1365713674 // Type parameters from outer context referenced by source type are fixed by instantiation of the source type
1365813675 inferTypesWithContext(context, instantiateType(source, contextualMapper), target);
@@ -14353,7 +14370,7 @@ namespace ts {
1435314370 let candidate: Signature;
1435414371 let typeArgumentsAreValid: boolean;
1435514372 const inferenceContext = originalCandidate.typeParameters
14356- ? createInferenceContext(originalCandidate, /*inferUnionTypes*/ false)
14373+ ? createInferenceContext(originalCandidate, /*inferUnionTypes*/ false, /*useAnyForNoInferences*/ isInJavaScriptFile(node) )
1435714374 : undefined;
1435814375
1435914376 while (true) {
@@ -16233,7 +16250,7 @@ namespace ts {
1623316250 function isLiteralContextualType(contextualType: Type) {
1623416251 if (contextualType) {
1623516252 if (contextualType.flags & TypeFlags.TypeVariable) {
16236- const constraint = getBaseConstraintOfType(<TypeVariable> contextualType) || emptyObjectType;
16253+ const constraint = getBaseConstraintOfType(contextualType) || emptyObjectType;
1623716254 // If the type parameter is constrained to the base primitive type we're checking for,
1623816255 // consider this a literal context. For example, given a type parameter 'T extends string',
1623916256 // this causes us to infer string literal types for T.
@@ -17123,7 +17140,7 @@ namespace ts {
1712317140 // Check if we're indexing with a numeric type and the object type is a generic
1712417141 // type with a constraint that has a numeric index signature.
1712517142 if (maybeTypeOfKind(objectType, TypeFlags.TypeVariable) && isTypeOfKind(indexType, TypeFlags.NumberLike)) {
17126- const constraint = getBaseConstraintOfType(<TypeVariable | UnionOrIntersectionType> objectType);
17143+ const constraint = getBaseConstraintOfType(objectType);
1712717144 if (constraint && getIndexInfoOfType(constraint, IndexKind.Number)) {
1712817145 return type;
1712917146 }
0 commit comments