@@ -43,8 +43,6 @@ namespace ts {
43
43
let emptyArray: any[] = [];
44
44
let emptySymbols: SymbolTable = {};
45
45
46
- let jsxElementClassType: Type = undefined;
47
-
48
46
let compilerOptions = host.getCompilerOptions();
49
47
let languageVersion = compilerOptions.target || ScriptTarget.ES3;
50
48
let modulekind = compilerOptions.module ? compilerOptions.module : languageVersion === ScriptTarget.ES6 ? ModuleKind.ES6 : ModuleKind.None;
@@ -4940,6 +4938,9 @@ namespace ts {
4940
4938
}
4941
4939
return objectTypeRelatedTo(<ObjectType>source, <ObjectType>target, /*reportErrors*/ false);
4942
4940
}
4941
+ if (source.flags & TypeFlags.TypeParameter && target.flags & TypeFlags.TypeParameter) {
4942
+ return typeParameterIdenticalTo(<TypeParameter>source, <TypeParameter>target);
4943
+ }
4943
4944
if (source.flags & TypeFlags.Union && target.flags & TypeFlags.Union ||
4944
4945
source.flags & TypeFlags.Intersection && target.flags & TypeFlags.Intersection) {
4945
4946
if (result = eachTypeRelatedToSomeType(<UnionOrIntersectionType>source, <UnionOrIntersectionType>target)) {
@@ -5070,6 +5071,20 @@ namespace ts {
5070
5071
return result;
5071
5072
}
5072
5073
5074
+ function typeParameterIdenticalTo(source: TypeParameter, target: TypeParameter): Ternary {
5075
+ if (source.symbol.name !== target.symbol.name) {
5076
+ return Ternary.False;
5077
+ }
5078
+ // covers case when both type parameters does not have constraint (both equal to noConstraintType)
5079
+ if (source.constraint === target.constraint) {
5080
+ return Ternary.True;
5081
+ }
5082
+ if (source.constraint === noConstraintType || target.constraint === noConstraintType) {
5083
+ return Ternary.False;
5084
+ }
5085
+ return isIdenticalTo(source.constraint, target.constraint);
5086
+ }
5087
+
5073
5088
// Determine if two object types are related by structure. First, check if the result is already available in the global cache.
5074
5089
// Second, check if we have already started a comparison of the given two types in which case we assume the result to be true.
5075
5090
// Third, check if both types are part of deeply nested chains of generic type instantiations and if so assume the types are
@@ -5592,20 +5607,27 @@ namespace ts {
5592
5607
return Ternary.False;
5593
5608
}
5594
5609
}
5595
- // Check that the two signatures have the same number of type parameters. We might consider
5596
- // also checking that any type parameter constraints match, but that would require instantiating
5597
- // the constraints with a common set of type arguments to get relatable entities in places where
5598
- // type parameters occur in the constraints. The complexity of doing that doesn't seem worthwhile,
5599
- // particularly as we're comparing erased versions of the signatures below.
5600
- if ((source.typeParameters ? source.typeParameters.length : 0) !== (target.typeParameters ? target.typeParameters.length : 0)) {
5610
+ let result = Ternary.True;
5611
+ if (source.typeParameters && target.typeParameters) {
5612
+ if (source.typeParameters.length !== target.typeParameters.length) {
5613
+ return Ternary.False;
5614
+ }
5615
+ for (let i = 0, len = source.typeParameters.length; i < len; ++i) {
5616
+ let related = compareTypes(source.typeParameters[i], target.typeParameters[i]);
5617
+ if (!related) {
5618
+ return Ternary.False;
5619
+ }
5620
+ result &= related;
5621
+ }
5622
+ }
5623
+ else if (source.typeParameters || target.typeParameters) {
5601
5624
return Ternary.False;
5602
5625
}
5603
5626
// Spec 1.0 Section 3.8.3 & 3.8.4:
5604
5627
// M and N (the signatures) are instantiated using type Any as the type argument for all type parameters declared by M and N
5605
5628
source = getErasedSignature(source);
5606
5629
target = getErasedSignature(target);
5607
- let result = Ternary.True;
5608
- const targetLen = target.parameters.length;
5630
+ let targetLen = target.parameters.length;
5609
5631
for (let i = 0; i < targetLen; i++) {
5610
5632
let s = isRestParameterIndex(source, i) ? getRestTypeOfSignature(source) : getTypeOfSymbol(source.parameters[i]);
5611
5633
let t = isRestParameterIndex(target, i) ? getRestTypeOfSignature(target) : getTypeOfSymbol(target.parameters[i]);
@@ -5906,17 +5928,6 @@ namespace ts {
5906
5928
}
5907
5929
5908
5930
function inferFromTypes(source: Type, target: Type) {
5909
- if (source.flags & TypeFlags.Union && target.flags & TypeFlags.Union ||
5910
- source.flags & TypeFlags.Intersection && target.flags & TypeFlags.Intersection) {
5911
- // Source and target are both unions or both intersections. To improve the quality of
5912
- // inferences we first reduce the types by removing constituents that are identically
5913
- // matched by a constituent in the other type. For example, when inferring from
5914
- // 'string | string[]' to 'string | T', we reduce the types to 'string[]' and 'T'.
5915
- const reducedSource = reduceUnionOrIntersectionType(<UnionOrIntersectionType>source, <UnionOrIntersectionType>target);
5916
- const reducedTarget = reduceUnionOrIntersectionType(<UnionOrIntersectionType>target, <UnionOrIntersectionType>source);
5917
- source = reducedSource;
5918
- target = reducedTarget;
5919
- }
5920
5931
if (target.flags & TypeFlags.TypeParameter) {
5921
5932
// If target is a type parameter, make an inference, unless the source type contains
5922
5933
// the anyFunctionType (the wildcard type that's used to avoid contextually typing functions).
@@ -5927,7 +5938,8 @@ namespace ts {
5927
5938
if (source.flags & TypeFlags.ContainsAnyFunctionType) {
5928
5939
return;
5929
5940
}
5930
- const typeParameters = context.typeParameters;
5941
+
5942
+ let typeParameters = context.typeParameters;
5931
5943
for (let i = 0; i < typeParameters.length; i++) {
5932
5944
if (target === typeParameters[i]) {
5933
5945
let inferences = context.inferences[i];
@@ -5999,9 +6011,12 @@ namespace ts {
5999
6011
}
6000
6012
else {
6001
6013
source = getApparentType(source);
6002
- if (source.flags & TypeFlags.ObjectType && (target.flags & (TypeFlags.Reference | TypeFlags.Tuple) ||
6003
- (target.flags & TypeFlags.Anonymous) && target.symbol && target.symbol.flags & (SymbolFlags.Method | SymbolFlags.TypeLiteral | SymbolFlags.Class))) {
6004
- // If source is an object type, and target is a type reference, a tuple type, the type of a method, or a type literal, infer from members
6014
+ if (source.flags & TypeFlags.ObjectType && (
6015
+ target.flags & TypeFlags.Reference && (<TypeReference>target).typeArguments ||
6016
+ target.flags & TypeFlags.Tuple ||
6017
+ target.flags & TypeFlags.Anonymous && target.symbol && target.symbol.flags & (SymbolFlags.Method | SymbolFlags.TypeLiteral | SymbolFlags.Class))) {
6018
+ // If source is an object type, and target is a type reference with type arguments, a tuple type,
6019
+ // the type of a method, or a type literal, infer from members
6005
6020
if (isInProcess(source, target)) {
6006
6021
return;
6007
6022
}
@@ -6074,41 +6089,6 @@ namespace ts {
6074
6089
}
6075
6090
}
6076
6091
6077
- function typeIdenticalToSomeType(source: Type, target: UnionOrIntersectionType): boolean {
6078
- for (const t of target.types) {
6079
- if (isTypeIdenticalTo(source, t)) {
6080
- return true;
6081
- }
6082
- }
6083
- return false;
6084
- }
6085
-
6086
- /**
6087
- * Return the reduced form of the source type. This type is computed by by removing all source
6088
- * constituents that have an identical match in the target type.
6089
- */
6090
- function reduceUnionOrIntersectionType(source: UnionOrIntersectionType, target: UnionOrIntersectionType) {
6091
- let sourceTypes = source.types;
6092
- let sourceIndex = 0;
6093
- let modified = false;
6094
- while (sourceIndex < sourceTypes.length) {
6095
- if (typeIdenticalToSomeType(sourceTypes[sourceIndex], target)) {
6096
- if (!modified) {
6097
- sourceTypes = sourceTypes.slice(0);
6098
- modified = true;
6099
- }
6100
- sourceTypes.splice(sourceIndex, 1);
6101
- }
6102
- else {
6103
- sourceIndex++;
6104
- }
6105
- }
6106
- if (modified) {
6107
- return source.flags & TypeFlags.Union ? getUnionType(sourceTypes, /*noSubtypeReduction*/ true) : getIntersectionType(sourceTypes);
6108
- }
6109
- return source;
6110
- }
6111
-
6112
6092
function getInferenceCandidates(context: InferenceContext, index: number): Type[] {
6113
6093
let inferences = context.inferences[index];
6114
6094
return inferences.primary || inferences.secondary || emptyArray;
@@ -7882,6 +7862,7 @@ namespace ts {
7882
7862
return prop || unknownSymbol;
7883
7863
}
7884
7864
7865
+ let jsxElementClassType: Type = undefined;
7885
7866
function getJsxGlobalElementClassType(): Type {
7886
7867
if (!jsxElementClassType) {
7887
7868
jsxElementClassType = getExportedTypeFromNamespace(JsxNames.JSX, JsxNames.ElementClass);
0 commit comments