@@ -9044,7 +9044,7 @@ namespace ts {
9044
9044
}
9045
9045
9046
9046
function getSubstitutionType(typeVariable: TypeVariable, substitute: Type) {
9047
- if (substitute.flags & TypeFlags.AnyOrUnknown) {
9047
+ if (substitute.flags & TypeFlags.AnyOrUnknown || substitute === typeVariable ) {
9048
9048
return typeVariable;
9049
9049
}
9050
9050
const id = `${getTypeId(typeVariable)}>${getTypeId(substitute)}`;
@@ -10194,7 +10194,9 @@ namespace ts {
10194
10194
}
10195
10195
10196
10196
function getSimplifiedType(type: Type, writing: boolean): Type {
10197
- return type.flags & TypeFlags.IndexedAccess ? getSimplifiedIndexedAccessType(<IndexedAccessType>type, writing) : type;
10197
+ return type.flags & TypeFlags.IndexedAccess ? getSimplifiedIndexedAccessType(<IndexedAccessType>type, writing) :
10198
+ type.flags & TypeFlags.Conditional ? getSimplifiedConditionalType(<ConditionalType>type, writing) :
10199
+ type;
10198
10200
}
10199
10201
10200
10202
function distributeIndexOverObjectType(objectType: Type, indexType: Type, writing: boolean) {
@@ -10257,6 +10259,32 @@ namespace ts {
10257
10259
return type[cache] = type;
10258
10260
}
10259
10261
10262
+ function getSimplifiedConditionalType(type: ConditionalType, writing: boolean) {
10263
+ const falseType = getFalseTypeFromConditionalType(type);
10264
+ const trueType = getTrueTypeFromConditionalType(type);
10265
+ const checkType = type.checkType;
10266
+ const extendsType = type.extendsType;
10267
+ // Simplifications for types of the form `T extends U ? T : never` and `T extends U ? never : T`.
10268
+ if (falseType.flags & TypeFlags.Never && getActualTypeVariable(trueType) === getActualTypeVariable(checkType)) {
10269
+ if (checkType.flags & TypeFlags.Any || isTypeAssignableTo(getRestrictiveInstantiation(checkType), getRestrictiveInstantiation(extendsType))) { // Always true
10270
+ return getSimplifiedType(trueType, writing);
10271
+ }
10272
+ else if (isIntersectionEmpty(checkType, extendsType)) { // Always false
10273
+ return neverType;
10274
+ }
10275
+ }
10276
+ else if (trueType.flags & TypeFlags.Never && getActualTypeVariable(falseType) === getActualTypeVariable(checkType)) {
10277
+ if (!(checkType.flags & TypeFlags.Any) && isTypeAssignableTo(getRestrictiveInstantiation(checkType), getRestrictiveInstantiation(extendsType))) { // Always true
10278
+ return neverType;
10279
+ }
10280
+ else if (checkType.flags & TypeFlags.Any || isIntersectionEmpty(checkType, extendsType)) { // Always false
10281
+ return getSimplifiedType(falseType, writing);
10282
+ }
10283
+ }
10284
+
10285
+ return type;
10286
+ }
10287
+
10260
10288
function substituteIndexedMappedType(objectType: MappedType, index: Type) {
10261
10289
const mapper = createTypeMapper([getTypeParameterFromMappedType(objectType)], [index]);
10262
10290
const templateMapper = combineTypeMappers(objectType.mapper, mapper);
@@ -12431,10 +12459,10 @@ namespace ts {
12431
12459
if (target.flags & TypeFlags.Substitution) {
12432
12460
target = (<SubstitutionType>target).typeVariable;
12433
12461
}
12434
- if (source.flags & TypeFlags.IndexedAccess ) {
12462
+ if (source.flags & TypeFlags.Simplifiable ) {
12435
12463
source = getSimplifiedType(source, /*writing*/ false);
12436
12464
}
12437
- if (target.flags & TypeFlags.IndexedAccess ) {
12465
+ if (target.flags & TypeFlags.Simplifiable ) {
12438
12466
target = getSimplifiedType(target, /*writing*/ true);
12439
12467
}
12440
12468
0 commit comments