@@ -3040,7 +3040,7 @@ namespace ts {
3040
3040
return createConditionalTypeNode(checkTypeNode, extendsTypeNode, trueTypeNode, falseTypeNode);
3041
3041
}
3042
3042
if (type.flags & TypeFlags.Substitution) {
3043
- return typeToTypeNodeHelper((<SubstitutionType>type).typeParameter , context);
3043
+ return typeToTypeNodeHelper((<SubstitutionType>type).typeVariable , context);
3044
3044
}
3045
3045
3046
3046
Debug.fail("Should be unreachable.");
@@ -7305,7 +7305,7 @@ namespace ts {
7305
7305
const res = tryGetDeclaredTypeOfSymbol(symbol);
7306
7306
if (res) {
7307
7307
return checkNoTypeArguments(node, symbol) ?
7308
- res.flags & TypeFlags.TypeParameter ? getConstrainedTypeParameter (<TypeParameter>res, node) : res :
7308
+ res.flags & TypeFlags.TypeParameter ? getConstrainedTypeVariable (<TypeParameter>res, node) : res :
7309
7309
unknownType;
7310
7310
}
7311
7311
@@ -7344,25 +7344,36 @@ namespace ts {
7344
7344
}
7345
7345
}
7346
7346
7347
- function getSubstitutionType(typeParameter: TypeParameter , substitute: Type) {
7347
+ function getSubstitutionType(typeVariable: TypeVariable , substitute: Type) {
7348
7348
const result = <SubstitutionType>createType(TypeFlags.Substitution);
7349
- result.typeParameter = typeParameter ;
7349
+ result.typeVariable = typeVariable ;
7350
7350
result.substitute = substitute;
7351
7351
return result;
7352
7352
}
7353
7353
7354
- function getConstrainedTypeParameter(typeParameter: TypeParameter, node: Node) {
7354
+ function isUnaryTupleTypeNode(node: TypeNode) {
7355
+ return node.kind === SyntaxKind.TupleType && (<TupleTypeNode>node).elementTypes.length === 1;
7356
+ }
7357
+
7358
+ function getImpliedConstraint(typeVariable: TypeVariable, checkNode: TypeNode, extendsNode: TypeNode): Type {
7359
+ return isUnaryTupleTypeNode(checkNode) && isUnaryTupleTypeNode(extendsNode) ? getImpliedConstraint(typeVariable, (<TupleTypeNode>checkNode).elementTypes[0], (<TupleTypeNode>extendsNode).elementTypes[0]) :
7360
+ getActualTypeVariable(getTypeFromTypeNode(checkNode)) === typeVariable ? getTypeFromTypeNode(extendsNode) :
7361
+ undefined;
7362
+ }
7363
+
7364
+ function getConstrainedTypeVariable(typeVariable: TypeVariable, node: Node) {
7355
7365
let constraints: Type[];
7356
7366
while (isPartOfTypeNode(node)) {
7357
7367
const parent = node.parent;
7358
7368
if (parent.kind === SyntaxKind.ConditionalType && node === (<ConditionalTypeNode>parent).trueType) {
7359
- if (getTypeFromTypeNode((<ConditionalTypeNode>parent).checkType) === typeParameter) {
7360
- constraints = append(constraints, getTypeFromTypeNode((<ConditionalTypeNode>parent).extendsType));
7369
+ const constraint = getImpliedConstraint(typeVariable, (<ConditionalTypeNode>parent).checkType, (<ConditionalTypeNode>parent).extendsType);
7370
+ if (constraint) {
7371
+ constraints = append(constraints, constraint);
7361
7372
}
7362
7373
}
7363
7374
node = parent;
7364
7375
}
7365
- return constraints ? getSubstitutionType(typeParameter , getIntersectionType(append(constraints, typeParameter ))) : typeParameter ;
7376
+ return constraints ? getSubstitutionType(typeVariable , getIntersectionType(append(constraints, typeVariable ))) : typeVariable ;
7366
7377
}
7367
7378
7368
7379
function isJSDocTypeReference(node: TypeReferenceType): node is TypeReferenceNode {
@@ -8258,7 +8269,13 @@ namespace ts {
8258
8269
function getTypeFromIndexedAccessTypeNode(node: IndexedAccessTypeNode) {
8259
8270
const links = getNodeLinks(node);
8260
8271
if (!links.resolvedType) {
8261
- links.resolvedType = getIndexedAccessType(getTypeFromTypeNode(node.objectType), getTypeFromTypeNode(node.indexType), node);
8272
+ const objectType = getTypeFromTypeNode(node.objectType);
8273
+ const indexType = getTypeFromTypeNode(node.indexType);
8274
+ const resolved = getIndexedAccessType(objectType, indexType, node);
8275
+ links.resolvedType = resolved.flags & TypeFlags.IndexedAccess &&
8276
+ (<IndexedAccessType>resolved).objectType === objectType &&
8277
+ (<IndexedAccessType>resolved).indexType === indexType ?
8278
+ getConstrainedTypeVariable(<IndexedAccessType>resolved, node) : resolved;
8262
8279
}
8263
8280
return links.resolvedType;
8264
8281
}
@@ -8278,8 +8295,8 @@ namespace ts {
8278
8295
return links.resolvedType;
8279
8296
}
8280
8297
8281
- function getActualTypeParameter (type: Type) {
8282
- return type.flags & TypeFlags.Substitution ? (<SubstitutionType>type).typeParameter : type;
8298
+ function getActualTypeVariable (type: Type) {
8299
+ return type.flags & TypeFlags.Substitution ? (<SubstitutionType>type).typeVariable : type;
8283
8300
}
8284
8301
8285
8302
function getConditionalType(root: ConditionalRoot, mapper: TypeMapper): Type {
@@ -8323,7 +8340,7 @@ namespace ts {
8323
8340
}
8324
8341
}
8325
8342
// Return a deferred type for a check that is neither definitely true nor definitely false
8326
- const erasedCheckType = getActualTypeParameter (checkType);
8343
+ const erasedCheckType = getActualTypeVariable (checkType);
8327
8344
const result = <ConditionalType>createType(TypeFlags.Conditional);
8328
8345
result.root = root;
8329
8346
result.checkType = erasedCheckType;
@@ -9043,7 +9060,7 @@ namespace ts {
9043
9060
return getConditionalTypeInstantiation(<ConditionalType>type, combineTypeMappers((<ConditionalType>type).mapper, mapper));
9044
9061
}
9045
9062
if (type.flags & TypeFlags.Substitution) {
9046
- return mapper ((<SubstitutionType>type).typeParameter );
9063
+ return instantiateType ((<SubstitutionType>type).typeVariable, mapper );
9047
9064
}
9048
9065
}
9049
9066
return type;
@@ -9650,10 +9667,10 @@ namespace ts {
9650
9667
target = (<LiteralType>target).regularType;
9651
9668
}
9652
9669
if (source.flags & TypeFlags.Substitution) {
9653
- source = relation === definitelyAssignableRelation ? (<SubstitutionType>source).typeParameter : (<SubstitutionType>source).substitute;
9670
+ source = relation === definitelyAssignableRelation ? (<SubstitutionType>source).typeVariable : (<SubstitutionType>source).substitute;
9654
9671
}
9655
9672
if (target.flags & TypeFlags.Substitution) {
9656
- target = (<SubstitutionType>target).typeParameter ;
9673
+ target = (<SubstitutionType>target).typeVariable ;
9657
9674
}
9658
9675
9659
9676
// both types are the same - covers 'they are the same primitive type or both are Any' or the same type parameter cases
0 commit comments