diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3b1771d209664..948be393e006d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8144,7 +8144,7 @@ namespace ts { // types with type parameters mapped to the wildcard type, the most permissive instantiations // possible (the wildcard type is assignable to and from all types). If those are not related, // then no instatiations will be and we can just return the false branch type. - if (!isTypeAssignableTo(getWildcardInstantiation(checkType), getWildcardInstantiation(extendsType))) { + if (!typeMaybeAssignableTo(getWildcardInstantiation(checkType), getWildcardInstantiation(extendsType))) { return instantiateType(baseFalseType, mapper); } // The check could be true for some instantiation diff --git a/tests/baselines/reference/conditionalTypes1.errors.txt b/tests/baselines/reference/conditionalTypes1.errors.txt index a7717d182631c..4f515876b1ef7 100644 --- a/tests/baselines/reference/conditionalTypes1.errors.txt +++ b/tests/baselines/reference/conditionalTypes1.errors.txt @@ -344,4 +344,24 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(157,5): error TS2 type T50 = IsNever; // true type T51 = IsNever; // false type T52 = IsNever; // false + + // Repros from #21664 + + type Eq = T extends U ? U extends T ? true : false : false; + type T60 = Eq; // true + type T61 = Eq; // false + type T62 = Eq; // false + type T63 = Eq; // true + + type Eq1 = Eq extends false ? false : true; + type T70 = Eq1; // true + type T71 = Eq1; // false + type T72 = Eq1; // false + type T73 = Eq1; // true + + type Eq2 = Eq extends true ? true : false; + type T80 = Eq2; // true + type T81 = Eq2; // false + type T82 = Eq2; // false + type T83 = Eq2; // true \ No newline at end of file diff --git a/tests/baselines/reference/conditionalTypes1.js b/tests/baselines/reference/conditionalTypes1.js index 0da7794a76214..3ca5966ce8eb9 100644 --- a/tests/baselines/reference/conditionalTypes1.js +++ b/tests/baselines/reference/conditionalTypes1.js @@ -204,6 +204,26 @@ type IsNever = T extends never ? true : false; type T50 = IsNever; // true type T51 = IsNever; // false type T52 = IsNever; // false + +// Repros from #21664 + +type Eq = T extends U ? U extends T ? true : false : false; +type T60 = Eq; // true +type T61 = Eq; // false +type T62 = Eq; // false +type T63 = Eq; // true + +type Eq1 = Eq extends false ? false : true; +type T70 = Eq1; // true +type T71 = Eq1; // false +type T72 = Eq1; // false +type T73 = Eq1; // true + +type Eq2 = Eq extends true ? true : false; +type T80 = Eq2; // true +type T81 = Eq2; // false +type T82 = Eq2; // false +type T83 = Eq2; // true //// [conditionalTypes1.js] @@ -415,3 +435,18 @@ declare type IsNever = T extends never ? true : false; declare type T50 = IsNever; declare type T51 = IsNever; declare type T52 = IsNever; +declare type Eq = T extends U ? U extends T ? true : false : false; +declare type T60 = Eq; +declare type T61 = Eq; +declare type T62 = Eq; +declare type T63 = Eq; +declare type Eq1 = Eq extends false ? false : true; +declare type T70 = Eq1; +declare type T71 = Eq1; +declare type T72 = Eq1; +declare type T73 = Eq1; +declare type Eq2 = Eq extends true ? true : false; +declare type T80 = Eq2; +declare type T81 = Eq2; +declare type T82 = Eq2; +declare type T83 = Eq2; diff --git a/tests/baselines/reference/conditionalTypes1.symbols b/tests/baselines/reference/conditionalTypes1.symbols index 9d3b79d5c30a0..276c1af740a62 100644 --- a/tests/baselines/reference/conditionalTypes1.symbols +++ b/tests/baselines/reference/conditionalTypes1.symbols @@ -777,3 +777,78 @@ type T52 = IsNever; // false >T52 : Symbol(T52, Decl(conditionalTypes1.ts, 203, 27)) >IsNever : Symbol(IsNever, Decl(conditionalTypes1.ts, 198, 47)) +// Repros from #21664 + +type Eq = T extends U ? U extends T ? true : false : false; +>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 204, 24)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 208, 8)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 208, 10)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 208, 8)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 208, 10)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 208, 10)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 208, 8)) + +type T60 = Eq; // true +>T60 : Symbol(T60, Decl(conditionalTypes1.ts, 208, 65)) +>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 204, 24)) + +type T61 = Eq; // false +>T61 : Symbol(T61, Decl(conditionalTypes1.ts, 209, 26)) +>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 204, 24)) + +type T62 = Eq; // false +>T62 : Symbol(T62, Decl(conditionalTypes1.ts, 210, 27)) +>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 204, 24)) + +type T63 = Eq; // true +>T63 : Symbol(T63, Decl(conditionalTypes1.ts, 211, 27)) +>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 204, 24)) + +type Eq1 = Eq extends false ? false : true; +>Eq1 : Symbol(Eq1, Decl(conditionalTypes1.ts, 212, 28)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 214, 9)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 214, 11)) +>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 204, 24)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 214, 9)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 214, 11)) + +type T70 = Eq1; // true +>T70 : Symbol(T70, Decl(conditionalTypes1.ts, 214, 55)) +>Eq1 : Symbol(Eq1, Decl(conditionalTypes1.ts, 212, 28)) + +type T71 = Eq1; // false +>T71 : Symbol(T71, Decl(conditionalTypes1.ts, 215, 27)) +>Eq1 : Symbol(Eq1, Decl(conditionalTypes1.ts, 212, 28)) + +type T72 = Eq1; // false +>T72 : Symbol(T72, Decl(conditionalTypes1.ts, 216, 28)) +>Eq1 : Symbol(Eq1, Decl(conditionalTypes1.ts, 212, 28)) + +type T73 = Eq1; // true +>T73 : Symbol(T73, Decl(conditionalTypes1.ts, 217, 28)) +>Eq1 : Symbol(Eq1, Decl(conditionalTypes1.ts, 212, 28)) + +type Eq2 = Eq extends true ? true : false; +>Eq2 : Symbol(Eq2, Decl(conditionalTypes1.ts, 218, 29)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 220, 9)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 220, 11)) +>Eq : Symbol(Eq, Decl(conditionalTypes1.ts, 204, 24)) +>T : Symbol(T, Decl(conditionalTypes1.ts, 220, 9)) +>U : Symbol(U, Decl(conditionalTypes1.ts, 220, 11)) + +type T80 = Eq2; // true +>T80 : Symbol(T80, Decl(conditionalTypes1.ts, 220, 54)) +>Eq2 : Symbol(Eq2, Decl(conditionalTypes1.ts, 218, 29)) + +type T81 = Eq2; // false +>T81 : Symbol(T81, Decl(conditionalTypes1.ts, 221, 27)) +>Eq2 : Symbol(Eq2, Decl(conditionalTypes1.ts, 218, 29)) + +type T82 = Eq2; // false +>T82 : Symbol(T82, Decl(conditionalTypes1.ts, 222, 28)) +>Eq2 : Symbol(Eq2, Decl(conditionalTypes1.ts, 218, 29)) + +type T83 = Eq2; // true +>T83 : Symbol(T83, Decl(conditionalTypes1.ts, 223, 28)) +>Eq2 : Symbol(Eq2, Decl(conditionalTypes1.ts, 218, 29)) + diff --git a/tests/baselines/reference/conditionalTypes1.types b/tests/baselines/reference/conditionalTypes1.types index df825ecd40b7d..e8a50e60fcc4c 100644 --- a/tests/baselines/reference/conditionalTypes1.types +++ b/tests/baselines/reference/conditionalTypes1.types @@ -883,3 +883,111 @@ type T52 = IsNever; // false >T52 : false >IsNever : IsNever +// Repros from #21664 + +type Eq = T extends U ? U extends T ? true : false : false; +>Eq : Eq +>T : T +>U : U +>T : T +>U : U +>U : U +>T : T +>true : true +>false : false +>false : false + +type T60 = Eq; // true +>T60 : true +>Eq : Eq +>true : true +>true : true + +type T61 = Eq; // false +>T61 : false +>Eq : Eq +>true : true +>false : false + +type T62 = Eq; // false +>T62 : false +>Eq : Eq +>false : false +>true : true + +type T63 = Eq; // true +>T63 : true +>Eq : Eq +>false : false +>false : false + +type Eq1 = Eq extends false ? false : true; +>Eq1 : Eq1 +>T : T +>U : U +>Eq : Eq +>T : T +>U : U +>false : false +>false : false +>true : true + +type T70 = Eq1; // true +>T70 : true +>Eq1 : Eq1 +>true : true +>true : true + +type T71 = Eq1; // false +>T71 : false +>Eq1 : Eq1 +>true : true +>false : false + +type T72 = Eq1; // false +>T72 : false +>Eq1 : Eq1 +>false : false +>true : true + +type T73 = Eq1; // true +>T73 : true +>Eq1 : Eq1 +>false : false +>false : false + +type Eq2 = Eq extends true ? true : false; +>Eq2 : Eq2 +>T : T +>U : U +>Eq : Eq +>T : T +>U : U +>true : true +>true : true +>false : false + +type T80 = Eq2; // true +>T80 : true +>Eq2 : Eq2 +>true : true +>true : true + +type T81 = Eq2; // false +>T81 : false +>Eq2 : Eq2 +>true : true +>false : false + +type T82 = Eq2; // false +>T82 : false +>Eq2 : Eq2 +>false : false +>true : true + +type T83 = Eq2; // true +>T83 : true +>Eq2 : Eq2 +>false : false +>false : false + diff --git a/tests/cases/conformance/types/conditional/conditionalTypes1.ts b/tests/cases/conformance/types/conditional/conditionalTypes1.ts index a6169d428ff25..7ac6255b7d59c 100644 --- a/tests/cases/conformance/types/conditional/conditionalTypes1.ts +++ b/tests/cases/conformance/types/conditional/conditionalTypes1.ts @@ -206,3 +206,23 @@ type IsNever = T extends never ? true : false; type T50 = IsNever; // true type T51 = IsNever; // false type T52 = IsNever; // false + +// Repros from #21664 + +type Eq = T extends U ? U extends T ? true : false : false; +type T60 = Eq; // true +type T61 = Eq; // false +type T62 = Eq; // false +type T63 = Eq; // true + +type Eq1 = Eq extends false ? false : true; +type T70 = Eq1; // true +type T71 = Eq1; // false +type T72 = Eq1; // false +type T73 = Eq1; // true + +type Eq2 = Eq extends true ? true : false; +type T80 = Eq2; // true +type T81 = Eq2; // false +type T82 = Eq2; // false +type T83 = Eq2; // true