Skip to content

Commit 7ad8182

Browse files
authored
Merge pull request #21737 from Microsoft/fixDeferredConditional
Fix definitely false check in conditional types
2 parents ed941c2 + 5e84b0d commit 7ad8182

File tree

6 files changed

+259
-1
lines changed

6 files changed

+259
-1
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8190,7 +8190,7 @@ namespace ts {
81908190
// types with type parameters mapped to the wildcard type, the most permissive instantiations
81918191
// possible (the wildcard type is assignable to and from all types). If those are not related,
81928192
// then no instatiations will be and we can just return the false branch type.
8193-
if (!isTypeAssignableTo(getWildcardInstantiation(checkType), getWildcardInstantiation(extendsType))) {
8193+
if (!typeMaybeAssignableTo(getWildcardInstantiation(checkType), getWildcardInstantiation(extendsType))) {
81948194
return instantiateType(baseFalseType, mapper);
81958195
}
81968196
// The check could be true for some instantiation

tests/baselines/reference/conditionalTypes1.errors.txt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,4 +344,24 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(157,5): error TS2
344344
type T50 = IsNever<never>; // true
345345
type T51 = IsNever<number>; // false
346346
type T52 = IsNever<any>; // false
347+
348+
// Repros from #21664
349+
350+
type Eq<T, U> = T extends U ? U extends T ? true : false : false;
351+
type T60 = Eq<true, true>; // true
352+
type T61 = Eq<true, false>; // false
353+
type T62 = Eq<false, true>; // false
354+
type T63 = Eq<false, false>; // true
355+
356+
type Eq1<T, U> = Eq<T, U> extends false ? false : true;
357+
type T70 = Eq1<true, true>; // true
358+
type T71 = Eq1<true, false>; // false
359+
type T72 = Eq1<false, true>; // false
360+
type T73 = Eq1<false, false>; // true
361+
362+
type Eq2<T, U> = Eq<T, U> extends true ? true : false;
363+
type T80 = Eq2<true, true>; // true
364+
type T81 = Eq2<true, false>; // false
365+
type T82 = Eq2<false, true>; // false
366+
type T83 = Eq2<false, false>; // true
347367

tests/baselines/reference/conditionalTypes1.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,26 @@ type IsNever<T> = T extends never ? true : false;
204204
type T50 = IsNever<never>; // true
205205
type T51 = IsNever<number>; // false
206206
type T52 = IsNever<any>; // false
207+
208+
// Repros from #21664
209+
210+
type Eq<T, U> = T extends U ? U extends T ? true : false : false;
211+
type T60 = Eq<true, true>; // true
212+
type T61 = Eq<true, false>; // false
213+
type T62 = Eq<false, true>; // false
214+
type T63 = Eq<false, false>; // true
215+
216+
type Eq1<T, U> = Eq<T, U> extends false ? false : true;
217+
type T70 = Eq1<true, true>; // true
218+
type T71 = Eq1<true, false>; // false
219+
type T72 = Eq1<false, true>; // false
220+
type T73 = Eq1<false, false>; // true
221+
222+
type Eq2<T, U> = Eq<T, U> extends true ? true : false;
223+
type T80 = Eq2<true, true>; // true
224+
type T81 = Eq2<true, false>; // false
225+
type T82 = Eq2<false, true>; // false
226+
type T83 = Eq2<false, false>; // true
207227

208228

209229
//// [conditionalTypes1.js]
@@ -415,3 +435,18 @@ declare type IsNever<T> = T extends never ? true : false;
415435
declare type T50 = IsNever<never>;
416436
declare type T51 = IsNever<number>;
417437
declare type T52 = IsNever<any>;
438+
declare type Eq<T, U> = T extends U ? U extends T ? true : false : false;
439+
declare type T60 = Eq<true, true>;
440+
declare type T61 = Eq<true, false>;
441+
declare type T62 = Eq<false, true>;
442+
declare type T63 = Eq<false, false>;
443+
declare type Eq1<T, U> = Eq<T, U> extends false ? false : true;
444+
declare type T70 = Eq1<true, true>;
445+
declare type T71 = Eq1<true, false>;
446+
declare type T72 = Eq1<false, true>;
447+
declare type T73 = Eq1<false, false>;
448+
declare type Eq2<T, U> = Eq<T, U> extends true ? true : false;
449+
declare type T80 = Eq2<true, true>;
450+
declare type T81 = Eq2<true, false>;
451+
declare type T82 = Eq2<false, true>;
452+
declare type T83 = Eq2<false, false>;

tests/baselines/reference/conditionalTypes1.symbols

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,3 +777,78 @@ type T52 = IsNever<any>; // false
777777
>T52 : Symbol(T52, Decl(conditionalTypes1.ts, 203, 27))
778778
>IsNever : Symbol(IsNever, Decl(conditionalTypes1.ts, 198, 47))
779779

780+
// Repros from #21664
781+
782+
type Eq<T, U> = T extends U ? U extends T ? true : false : false;
783+
>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 204, 24))
784+
>T : Symbol(T, Decl(conditionalTypes1.ts, 208, 8))
785+
>U : Symbol(U, Decl(conditionalTypes1.ts, 208, 10))
786+
>T : Symbol(T, Decl(conditionalTypes1.ts, 208, 8))
787+
>U : Symbol(U, Decl(conditionalTypes1.ts, 208, 10))
788+
>U : Symbol(U, Decl(conditionalTypes1.ts, 208, 10))
789+
>T : Symbol(T, Decl(conditionalTypes1.ts, 208, 8))
790+
791+
type T60 = Eq<true, true>; // true
792+
>T60 : Symbol(T60, Decl(conditionalTypes1.ts, 208, 65))
793+
>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 204, 24))
794+
795+
type T61 = Eq<true, false>; // false
796+
>T61 : Symbol(T61, Decl(conditionalTypes1.ts, 209, 26))
797+
>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 204, 24))
798+
799+
type T62 = Eq<false, true>; // false
800+
>T62 : Symbol(T62, Decl(conditionalTypes1.ts, 210, 27))
801+
>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 204, 24))
802+
803+
type T63 = Eq<false, false>; // true
804+
>T63 : Symbol(T63, Decl(conditionalTypes1.ts, 211, 27))
805+
>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 204, 24))
806+
807+
type Eq1<T, U> = Eq<T, U> extends false ? false : true;
808+
>Eq1 : Symbol(Eq1, Decl(conditionalTypes1.ts, 212, 28))
809+
>T : Symbol(T, Decl(conditionalTypes1.ts, 214, 9))
810+
>U : Symbol(U, Decl(conditionalTypes1.ts, 214, 11))
811+
>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 204, 24))
812+
>T : Symbol(T, Decl(conditionalTypes1.ts, 214, 9))
813+
>U : Symbol(U, Decl(conditionalTypes1.ts, 214, 11))
814+
815+
type T70 = Eq1<true, true>; // true
816+
>T70 : Symbol(T70, Decl(conditionalTypes1.ts, 214, 55))
817+
>Eq1 : Symbol(Eq1, Decl(conditionalTypes1.ts, 212, 28))
818+
819+
type T71 = Eq1<true, false>; // false
820+
>T71 : Symbol(T71, Decl(conditionalTypes1.ts, 215, 27))
821+
>Eq1 : Symbol(Eq1, Decl(conditionalTypes1.ts, 212, 28))
822+
823+
type T72 = Eq1<false, true>; // false
824+
>T72 : Symbol(T72, Decl(conditionalTypes1.ts, 216, 28))
825+
>Eq1 : Symbol(Eq1, Decl(conditionalTypes1.ts, 212, 28))
826+
827+
type T73 = Eq1<false, false>; // true
828+
>T73 : Symbol(T73, Decl(conditionalTypes1.ts, 217, 28))
829+
>Eq1 : Symbol(Eq1, Decl(conditionalTypes1.ts, 212, 28))
830+
831+
type Eq2<T, U> = Eq<T, U> extends true ? true : false;
832+
>Eq2 : Symbol(Eq2, Decl(conditionalTypes1.ts, 218, 29))
833+
>T : Symbol(T, Decl(conditionalTypes1.ts, 220, 9))
834+
>U : Symbol(U, Decl(conditionalTypes1.ts, 220, 11))
835+
>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 204, 24))
836+
>T : Symbol(T, Decl(conditionalTypes1.ts, 220, 9))
837+
>U : Symbol(U, Decl(conditionalTypes1.ts, 220, 11))
838+
839+
type T80 = Eq2<true, true>; // true
840+
>T80 : Symbol(T80, Decl(conditionalTypes1.ts, 220, 54))
841+
>Eq2 : Symbol(Eq2, Decl(conditionalTypes1.ts, 218, 29))
842+
843+
type T81 = Eq2<true, false>; // false
844+
>T81 : Symbol(T81, Decl(conditionalTypes1.ts, 221, 27))
845+
>Eq2 : Symbol(Eq2, Decl(conditionalTypes1.ts, 218, 29))
846+
847+
type T82 = Eq2<false, true>; // false
848+
>T82 : Symbol(T82, Decl(conditionalTypes1.ts, 222, 28))
849+
>Eq2 : Symbol(Eq2, Decl(conditionalTypes1.ts, 218, 29))
850+
851+
type T83 = Eq2<false, false>; // true
852+
>T83 : Symbol(T83, Decl(conditionalTypes1.ts, 223, 28))
853+
>Eq2 : Symbol(Eq2, Decl(conditionalTypes1.ts, 218, 29))
854+

tests/baselines/reference/conditionalTypes1.types

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -883,3 +883,111 @@ type T52 = IsNever<any>; // false
883883
>T52 : false
884884
>IsNever : IsNever<T>
885885

886+
// Repros from #21664
887+
888+
type Eq<T, U> = T extends U ? U extends T ? true : false : false;
889+
>Eq : Eq<T, U>
890+
>T : T
891+
>U : U
892+
>T : T
893+
>U : U
894+
>U : U
895+
>T : T
896+
>true : true
897+
>false : false
898+
>false : false
899+
900+
type T60 = Eq<true, true>; // true
901+
>T60 : true
902+
>Eq : Eq<T, U>
903+
>true : true
904+
>true : true
905+
906+
type T61 = Eq<true, false>; // false
907+
>T61 : false
908+
>Eq : Eq<T, U>
909+
>true : true
910+
>false : false
911+
912+
type T62 = Eq<false, true>; // false
913+
>T62 : false
914+
>Eq : Eq<T, U>
915+
>false : false
916+
>true : true
917+
918+
type T63 = Eq<false, false>; // true
919+
>T63 : true
920+
>Eq : Eq<T, U>
921+
>false : false
922+
>false : false
923+
924+
type Eq1<T, U> = Eq<T, U> extends false ? false : true;
925+
>Eq1 : Eq1<T, U>
926+
>T : T
927+
>U : U
928+
>Eq : Eq<T, U>
929+
>T : T
930+
>U : U
931+
>false : false
932+
>false : false
933+
>true : true
934+
935+
type T70 = Eq1<true, true>; // true
936+
>T70 : true
937+
>Eq1 : Eq1<T, U>
938+
>true : true
939+
>true : true
940+
941+
type T71 = Eq1<true, false>; // false
942+
>T71 : false
943+
>Eq1 : Eq1<T, U>
944+
>true : true
945+
>false : false
946+
947+
type T72 = Eq1<false, true>; // false
948+
>T72 : false
949+
>Eq1 : Eq1<T, U>
950+
>false : false
951+
>true : true
952+
953+
type T73 = Eq1<false, false>; // true
954+
>T73 : true
955+
>Eq1 : Eq1<T, U>
956+
>false : false
957+
>false : false
958+
959+
type Eq2<T, U> = Eq<T, U> extends true ? true : false;
960+
>Eq2 : Eq2<T, U>
961+
>T : T
962+
>U : U
963+
>Eq : Eq<T, U>
964+
>T : T
965+
>U : U
966+
>true : true
967+
>true : true
968+
>false : false
969+
970+
type T80 = Eq2<true, true>; // true
971+
>T80 : true
972+
>Eq2 : Eq2<T, U>
973+
>true : true
974+
>true : true
975+
976+
type T81 = Eq2<true, false>; // false
977+
>T81 : false
978+
>Eq2 : Eq2<T, U>
979+
>true : true
980+
>false : false
981+
982+
type T82 = Eq2<false, true>; // false
983+
>T82 : false
984+
>Eq2 : Eq2<T, U>
985+
>false : false
986+
>true : true
987+
988+
type T83 = Eq2<false, false>; // true
989+
>T83 : true
990+
>Eq2 : Eq2<T, U>
991+
>false : false
992+
>false : false
993+

tests/cases/conformance/types/conditional/conditionalTypes1.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,3 +206,23 @@ type IsNever<T> = T extends never ? true : false;
206206
type T50 = IsNever<never>; // true
207207
type T51 = IsNever<number>; // false
208208
type T52 = IsNever<any>; // false
209+
210+
// Repros from #21664
211+
212+
type Eq<T, U> = T extends U ? U extends T ? true : false : false;
213+
type T60 = Eq<true, true>; // true
214+
type T61 = Eq<true, false>; // false
215+
type T62 = Eq<false, true>; // false
216+
type T63 = Eq<false, false>; // true
217+
218+
type Eq1<T, U> = Eq<T, U> extends false ? false : true;
219+
type T70 = Eq1<true, true>; // true
220+
type T71 = Eq1<true, false>; // false
221+
type T72 = Eq1<false, true>; // false
222+
type T73 = Eq1<false, false>; // true
223+
224+
type Eq2<T, U> = Eq<T, U> extends true ? true : false;
225+
type T80 = Eq2<true, true>; // true
226+
type T81 = Eq2<true, false>; // false
227+
type T82 = Eq2<false, true>; // false
228+
type T83 = Eq2<false, false>; // true

0 commit comments

Comments
 (0)