@@ -3973,7 +3973,7 @@ namespace ts {
3973
3973
return true;
3974
3974
}
3975
3975
if (type.flags & TypeFlags.TypeVariable) {
3976
- const constraint = getBaseConstraintOfType(<TypeVariable> type);
3976
+ const constraint = getBaseConstraintOfType(type);
3977
3977
return constraint && isValidBaseType(constraint) && isMixinConstructorType(constraint);
3978
3978
}
3979
3979
return false;
@@ -4989,16 +4989,32 @@ namespace ts {
4989
4989
}
4990
4990
4991
4991
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);
4993
4995
}
4994
4996
4995
4997
function getConstraintOfTypeParameter(typeParameter: TypeParameter): Type {
4996
4998
return hasNonCircularBaseConstraint(typeParameter) ? getConstraintFromTypeParameter(typeParameter) : undefined;
4997
4999
}
4998
5000
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;
5002
5018
}
5003
5019
5004
5020
function hasNonCircularBaseConstraint(type: TypeVariable): boolean {
@@ -5096,7 +5112,7 @@ namespace ts {
5096
5112
* type itself. Note that the apparent type of a union type is the union type itself.
5097
5113
*/
5098
5114
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;
5100
5116
return t.flags & TypeFlags.Intersection ? getApparentTypeOfIntersectionType(<IntersectionType>t) :
5101
5117
t.flags & TypeFlags.StringLike ? globalStringType :
5102
5118
t.flags & TypeFlags.NumberLike ? globalNumberType :
@@ -7921,7 +7937,7 @@ namespace ts {
7921
7937
}
7922
7938
// A type S is related to a type T[K] if S is related to A[K], where K is string-like and
7923
7939
// A is the apparent type of S.
7924
- const constraint = getBaseConstraintOfType(<IndexedAccessType> target);
7940
+ const constraint = getBaseConstraintOfType(target);
7925
7941
if (constraint) {
7926
7942
if (result = isRelatedTo(source, constraint, reportErrors)) {
7927
7943
errorInfo = saveErrorInfo;
@@ -7961,7 +7977,7 @@ namespace ts {
7961
7977
else if (source.flags & TypeFlags.IndexedAccess) {
7962
7978
// A type S[K] is related to a type T if A[K] is related to T, where K is string-like and
7963
7979
// A is the apparent type of S.
7964
- const constraint = getBaseConstraintOfType (<IndexedAccessType>source);
7980
+ const constraint = getConstraintOfType (<IndexedAccessType>source);
7965
7981
if (constraint) {
7966
7982
if (result = isRelatedTo(constraint, target, reportErrors)) {
7967
7983
errorInfo = saveErrorInfo;
@@ -9184,13 +9200,14 @@ namespace ts {
9184
9200
}
9185
9201
}
9186
9202
9187
- function createInferenceContext(signature: Signature, inferUnionTypes: boolean): InferenceContext {
9203
+ function createInferenceContext(signature: Signature, inferUnionTypes: boolean, useAnyForNoInferences: boolean ): InferenceContext {
9188
9204
const inferences = map(signature.typeParameters, createTypeInferencesObject);
9189
9205
return {
9190
9206
signature,
9191
9207
inferUnionTypes,
9192
9208
inferences,
9193
9209
inferredTypes: new Array(signature.typeParameters.length),
9210
+ useAnyForNoInferences
9194
9211
};
9195
9212
}
9196
9213
@@ -9604,7 +9621,7 @@ namespace ts {
9604
9621
getInferenceMapper(context)));
9605
9622
}
9606
9623
else {
9607
- inferredType = emptyObjectType;
9624
+ inferredType = context.useAnyForNoInferences ? anyType : emptyObjectType;
9608
9625
}
9609
9626
9610
9627
inferenceSucceeded = true;
@@ -9873,7 +9890,7 @@ namespace ts {
9873
9890
return strictNullChecks ? TypeFacts.ObjectStrictFacts : TypeFacts.ObjectFacts;
9874
9891
}
9875
9892
if (flags & TypeFlags.TypeVariable) {
9876
- return getTypeFacts(getBaseConstraintOfType(<TypeVariable> type) || emptyObjectType);
9893
+ return getTypeFacts(getBaseConstraintOfType(type) || emptyObjectType);
9877
9894
}
9878
9895
if (flags & TypeFlags.UnionOrIntersection) {
9879
9896
return getTypeFactsOfTypes((<UnionOrIntersectionType>type).types);
@@ -10685,7 +10702,7 @@ namespace ts {
10685
10702
return targetType;
10686
10703
}
10687
10704
if (type.flags & TypeFlags.TypeVariable) {
10688
- const constraint = getBaseConstraintOfType(<TypeVariable> type) || anyType;
10705
+ const constraint = getBaseConstraintOfType(type) || anyType;
10689
10706
if (isTypeSubtypeOf(targetType, constraint)) {
10690
10707
return getIntersectionType([type, targetType]);
10691
10708
}
@@ -13652,7 +13669,7 @@ namespace ts {
13652
13669
13653
13670
// Instantiate a generic signature in the context of a non-generic signature (section 3.8.5 in TypeScript spec)
13654
13671
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 );
13656
13673
forEachMatchingParameterType(contextualSignature, signature, (source, target) => {
13657
13674
// Type parameters from outer context referenced by source type are fixed by instantiation of the source type
13658
13675
inferTypesWithContext(context, instantiateType(source, contextualMapper), target);
@@ -14353,7 +14370,7 @@ namespace ts {
14353
14370
let candidate: Signature;
14354
14371
let typeArgumentsAreValid: boolean;
14355
14372
const inferenceContext = originalCandidate.typeParameters
14356
- ? createInferenceContext(originalCandidate, /*inferUnionTypes*/ false)
14373
+ ? createInferenceContext(originalCandidate, /*inferUnionTypes*/ false, /*useAnyForNoInferences*/ isInJavaScriptFile(node) )
14357
14374
: undefined;
14358
14375
14359
14376
while (true) {
@@ -16233,7 +16250,7 @@ namespace ts {
16233
16250
function isLiteralContextualType(contextualType: Type) {
16234
16251
if (contextualType) {
16235
16252
if (contextualType.flags & TypeFlags.TypeVariable) {
16236
- const constraint = getBaseConstraintOfType(<TypeVariable> contextualType) || emptyObjectType;
16253
+ const constraint = getBaseConstraintOfType(contextualType) || emptyObjectType;
16237
16254
// If the type parameter is constrained to the base primitive type we're checking for,
16238
16255
// consider this a literal context. For example, given a type parameter 'T extends string',
16239
16256
// this causes us to infer string literal types for T.
@@ -17123,7 +17140,7 @@ namespace ts {
17123
17140
// Check if we're indexing with a numeric type and the object type is a generic
17124
17141
// type with a constraint that has a numeric index signature.
17125
17142
if (maybeTypeOfKind(objectType, TypeFlags.TypeVariable) && isTypeOfKind(indexType, TypeFlags.NumberLike)) {
17126
- const constraint = getBaseConstraintOfType(<TypeVariable | UnionOrIntersectionType> objectType);
17143
+ const constraint = getBaseConstraintOfType(objectType);
17127
17144
if (constraint && getIndexInfoOfType(constraint, IndexKind.Number)) {
17128
17145
return type;
17129
17146
}
0 commit comments