@@ -9044,7 +9044,7 @@ namespace ts {
90449044 }
90459045
90469046 function getSubstitutionType(typeVariable: TypeVariable, substitute: Type) {
9047- if (substitute.flags & TypeFlags.AnyOrUnknown) {
9047+ if (substitute.flags & TypeFlags.AnyOrUnknown || substitute === typeVariable ) {
90489048 return typeVariable;
90499049 }
90509050 const id = `${getTypeId(typeVariable)}>${getTypeId(substitute)}`;
@@ -10194,7 +10194,9 @@ namespace ts {
1019410194 }
1019510195
1019610196 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;
1019810200 }
1019910201
1020010202 function distributeIndexOverObjectType(objectType: Type, indexType: Type, writing: boolean) {
@@ -10257,6 +10259,32 @@ namespace ts {
1025710259 return type[cache] = type;
1025810260 }
1025910261
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+
1026010288 function substituteIndexedMappedType(objectType: MappedType, index: Type) {
1026110289 const mapper = createTypeMapper([getTypeParameterFromMappedType(objectType)], [index]);
1026210290 const templateMapper = combineTypeMappers(objectType.mapper, mapper);
@@ -12431,10 +12459,10 @@ namespace ts {
1243112459 if (target.flags & TypeFlags.Substitution) {
1243212460 target = (<SubstitutionType>target).typeVariable;
1243312461 }
12434- if (source.flags & TypeFlags.IndexedAccess ) {
12462+ if (source.flags & TypeFlags.Simplifiable ) {
1243512463 source = getSimplifiedType(source, /*writing*/ false);
1243612464 }
12437- if (target.flags & TypeFlags.IndexedAccess ) {
12465+ if (target.flags & TypeFlags.Simplifiable ) {
1243812466 target = getSimplifiedType(target, /*writing*/ true);
1243912467 }
1244012468
0 commit comments