Skip to content

Commit 906ebe4

Browse files
authoredOct 19, 2022
Revert structuredTypeRelatedTo change and fix isUnitLikeType (#51076)
* Revert structuredTypeRelatedTo change, fix isUnitLikeType * Accept new baselines * Add regression tests * Fix formatting in test
1 parent 8ac4652 commit 906ebe4

File tree

6 files changed

+224
-5
lines changed

6 files changed

+224
-5
lines changed
 

‎src/compiler/checker.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -19663,7 +19663,7 @@ namespace ts {
1966319663
// For example, if `T extends 1 | 2` and `U extends 2 | 3` and we compare `T & U` to `T & U & (1 | 2 | 3)`
1966419664
if (!result && (source.flags & TypeFlags.Intersection || source.flags & TypeFlags.TypeParameter && target.flags & TypeFlags.Union)) {
1966519665
const constraint = getEffectiveConstraintOfIntersection(source.flags & TypeFlags.Intersection ? (source as IntersectionType).types: [source], !!(target.flags & TypeFlags.Union));
19666-
if (constraint && !(constraint.flags & TypeFlags.Never) && everyType(constraint, c => c !== source)) { // Skip comparison if expansion contains the source itself
19666+
if (constraint && everyType(constraint, c => c !== source)) { // Skip comparison if expansion contains the source itself
1966719667
// TODO: Stack errors so we get a pyramid for the "normal" comparison above, _and_ a second for this
1966819668
result = isRelatedTo(constraint, target, RecursionFlags.Source, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState);
1966919669
}
@@ -21630,8 +21630,7 @@ namespace ts {
2163021630
}
2163121631

2163221632
function isUnitLikeType(type: Type): boolean {
21633-
return type.flags & TypeFlags.Intersection ? some((type as IntersectionType).types, isUnitType) :
21634-
!!(type.flags & TypeFlags.Unit);
21633+
return isUnitType(getBaseConstraintOrType(type));
2163521634
}
2163621635

2163721636
function extractUnitType(type: Type) {

‎tests/baselines/reference/unknownControlFlow.errors.txt

+27
Original file line numberDiff line numberDiff line change
@@ -417,4 +417,31 @@ tests/cases/conformance/types/unknown/unknownControlFlow.ts(293,5): error TS2345
417417
value;
418418
}
419419
}
420+
421+
// Repro from #51009
422+
423+
type TypeA = {
424+
A: 'A',
425+
B: 'B',
426+
}
427+
428+
type TypeB = {
429+
A: 'A',
430+
B: 'B',
431+
C: 'C',
432+
}
433+
434+
type R<T extends keyof TypeA> =
435+
T extends keyof TypeB ? [TypeA[T], TypeB[T]] : never;
436+
437+
type R2<T extends PropertyKey> =
438+
T extends keyof TypeA ? T extends keyof TypeB ? [TypeA[T], TypeB[T]] : never : never;
439+
440+
// Repro from #51041
441+
442+
type AB = "A" | "B";
443+
444+
function x<T_AB extends AB>(x: T_AB & undefined, y: any) {
445+
let r2: never = y as T_AB & undefined;
446+
}
420447

‎tests/baselines/reference/unknownControlFlow.js

+43
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,33 @@ function doSomething2(value: unknown): void {
400400
value;
401401
}
402402
}
403+
404+
// Repro from #51009
405+
406+
type TypeA = {
407+
A: 'A',
408+
B: 'B',
409+
}
410+
411+
type TypeB = {
412+
A: 'A',
413+
B: 'B',
414+
C: 'C',
415+
}
416+
417+
type R<T extends keyof TypeA> =
418+
T extends keyof TypeB ? [TypeA[T], TypeB[T]] : never;
419+
420+
type R2<T extends PropertyKey> =
421+
T extends keyof TypeA ? T extends keyof TypeB ? [TypeA[T], TypeB[T]] : never : never;
422+
423+
// Repro from #51041
424+
425+
type AB = "A" | "B";
426+
427+
function x<T_AB extends AB>(x: T_AB & undefined, y: any) {
428+
let r2: never = y as T_AB & undefined;
429+
}
403430

404431

405432
//// [unknownControlFlow.js]
@@ -742,6 +769,9 @@ function doSomething2(value) {
742769
value;
743770
}
744771
}
772+
function x(x, y) {
773+
var r2 = y;
774+
}
745775

746776

747777
//// [unknownControlFlow.d.ts]
@@ -801,3 +831,16 @@ declare function fx10(x: string | number, y: number): void;
801831
declare function SendBlob(encoding: unknown): void;
802832
declare function doSomething1<T extends unknown>(value: T): T;
803833
declare function doSomething2(value: unknown): void;
834+
type TypeA = {
835+
A: 'A';
836+
B: 'B';
837+
};
838+
type TypeB = {
839+
A: 'A';
840+
B: 'B';
841+
C: 'C';
842+
};
843+
type R<T extends keyof TypeA> = T extends keyof TypeB ? [TypeA[T], TypeB[T]] : never;
844+
type R2<T extends PropertyKey> = T extends keyof TypeA ? T extends keyof TypeB ? [TypeA[T], TypeB[T]] : never : never;
845+
type AB = "A" | "B";
846+
declare function x<T_AB extends AB>(x: T_AB & undefined, y: any): void;

‎tests/baselines/reference/unknownControlFlow.symbols

+72
Original file line numberDiff line numberDiff line change
@@ -923,3 +923,75 @@ function doSomething2(value: unknown): void {
923923
}
924924
}
925925

926+
// Repro from #51009
927+
928+
type TypeA = {
929+
>TypeA : Symbol(TypeA, Decl(unknownControlFlow.ts, 400, 1))
930+
931+
A: 'A',
932+
>A : Symbol(A, Decl(unknownControlFlow.ts, 404, 14))
933+
934+
B: 'B',
935+
>B : Symbol(B, Decl(unknownControlFlow.ts, 405, 11))
936+
}
937+
938+
type TypeB = {
939+
>TypeB : Symbol(TypeB, Decl(unknownControlFlow.ts, 407, 1))
940+
941+
A: 'A',
942+
>A : Symbol(A, Decl(unknownControlFlow.ts, 409, 14))
943+
944+
B: 'B',
945+
>B : Symbol(B, Decl(unknownControlFlow.ts, 410, 11))
946+
947+
C: 'C',
948+
>C : Symbol(C, Decl(unknownControlFlow.ts, 411, 11))
949+
}
950+
951+
type R<T extends keyof TypeA> =
952+
>R : Symbol(R, Decl(unknownControlFlow.ts, 413, 1))
953+
>T : Symbol(T, Decl(unknownControlFlow.ts, 415, 7))
954+
>TypeA : Symbol(TypeA, Decl(unknownControlFlow.ts, 400, 1))
955+
956+
T extends keyof TypeB ? [TypeA[T], TypeB[T]] : never;
957+
>T : Symbol(T, Decl(unknownControlFlow.ts, 415, 7))
958+
>TypeB : Symbol(TypeB, Decl(unknownControlFlow.ts, 407, 1))
959+
>TypeA : Symbol(TypeA, Decl(unknownControlFlow.ts, 400, 1))
960+
>T : Symbol(T, Decl(unknownControlFlow.ts, 415, 7))
961+
>TypeB : Symbol(TypeB, Decl(unknownControlFlow.ts, 407, 1))
962+
>T : Symbol(T, Decl(unknownControlFlow.ts, 415, 7))
963+
964+
type R2<T extends PropertyKey> =
965+
>R2 : Symbol(R2, Decl(unknownControlFlow.ts, 416, 57))
966+
>T : Symbol(T, Decl(unknownControlFlow.ts, 418, 8))
967+
>PropertyKey : Symbol(PropertyKey, Decl(lib.es5.d.ts, --, --))
968+
969+
T extends keyof TypeA ? T extends keyof TypeB ? [TypeA[T], TypeB[T]] : never : never;
970+
>T : Symbol(T, Decl(unknownControlFlow.ts, 418, 8))
971+
>TypeA : Symbol(TypeA, Decl(unknownControlFlow.ts, 400, 1))
972+
>T : Symbol(T, Decl(unknownControlFlow.ts, 418, 8))
973+
>TypeB : Symbol(TypeB, Decl(unknownControlFlow.ts, 407, 1))
974+
>TypeA : Symbol(TypeA, Decl(unknownControlFlow.ts, 400, 1))
975+
>T : Symbol(T, Decl(unknownControlFlow.ts, 418, 8))
976+
>TypeB : Symbol(TypeB, Decl(unknownControlFlow.ts, 407, 1))
977+
>T : Symbol(T, Decl(unknownControlFlow.ts, 418, 8))
978+
979+
// Repro from #51041
980+
981+
type AB = "A" | "B";
982+
>AB : Symbol(AB, Decl(unknownControlFlow.ts, 419, 89))
983+
984+
function x<T_AB extends AB>(x: T_AB & undefined, y: any) {
985+
>x : Symbol(x, Decl(unknownControlFlow.ts, 423, 20))
986+
>T_AB : Symbol(T_AB, Decl(unknownControlFlow.ts, 425, 11))
987+
>AB : Symbol(AB, Decl(unknownControlFlow.ts, 419, 89))
988+
>x : Symbol(x, Decl(unknownControlFlow.ts, 425, 28))
989+
>T_AB : Symbol(T_AB, Decl(unknownControlFlow.ts, 425, 11))
990+
>y : Symbol(y, Decl(unknownControlFlow.ts, 425, 48))
991+
992+
let r2: never = y as T_AB & undefined;
993+
>r2 : Symbol(r2, Decl(unknownControlFlow.ts, 426, 7))
994+
>y : Symbol(y, Decl(unknownControlFlow.ts, 425, 48))
995+
>T_AB : Symbol(T_AB, Decl(unknownControlFlow.ts, 425, 11))
996+
}
997+

‎tests/baselines/reference/unknownControlFlow.types

+53-2
Original file line numberDiff line numberDiff line change
@@ -853,7 +853,7 @@ function fx2<T extends {}>(value: T & ({} | null)) {
853853
>42 : 42
854854

855855
value; // T & {}
856-
>value : T & {}
856+
>value : T & ({} | null)
857857
}
858858
else {
859859
value; // T & ({} | null)
@@ -872,7 +872,7 @@ function fx3<T extends {} | undefined>(value: T & ({} | null)) {
872872
>42 : 42
873873

874874
value; // T & {}
875-
>value : T & {}
875+
>value : T & ({} | null)
876876
}
877877
else {
878878
value; // T & ({} | null)
@@ -1025,3 +1025,54 @@ function doSomething2(value: unknown): void {
10251025
}
10261026
}
10271027

1028+
// Repro from #51009
1029+
1030+
type TypeA = {
1031+
>TypeA : { A: 'A'; B: 'B'; }
1032+
1033+
A: 'A',
1034+
>A : "A"
1035+
1036+
B: 'B',
1037+
>B : "B"
1038+
}
1039+
1040+
type TypeB = {
1041+
>TypeB : { A: 'A'; B: 'B'; C: 'C'; }
1042+
1043+
A: 'A',
1044+
>A : "A"
1045+
1046+
B: 'B',
1047+
>B : "B"
1048+
1049+
C: 'C',
1050+
>C : "C"
1051+
}
1052+
1053+
type R<T extends keyof TypeA> =
1054+
>R : R<T>
1055+
1056+
T extends keyof TypeB ? [TypeA[T], TypeB[T]] : never;
1057+
1058+
type R2<T extends PropertyKey> =
1059+
>R2 : R2<T>
1060+
1061+
T extends keyof TypeA ? T extends keyof TypeB ? [TypeA[T], TypeB[T]] : never : never;
1062+
1063+
// Repro from #51041
1064+
1065+
type AB = "A" | "B";
1066+
>AB : "A" | "B"
1067+
1068+
function x<T_AB extends AB>(x: T_AB & undefined, y: any) {
1069+
>x : <T_AB extends AB>(x: T_AB & undefined, y: any) => void
1070+
>x : T_AB & undefined
1071+
>y : any
1072+
1073+
let r2: never = y as T_AB & undefined;
1074+
>r2 : never
1075+
>y as T_AB & undefined : T_AB & undefined
1076+
>y : any
1077+
}
1078+

‎tests/cases/conformance/types/unknown/unknownControlFlow.ts

+27
Original file line numberDiff line numberDiff line change
@@ -402,3 +402,30 @@ function doSomething2(value: unknown): void {
402402
value;
403403
}
404404
}
405+
406+
// Repro from #51009
407+
408+
type TypeA = {
409+
A: 'A',
410+
B: 'B',
411+
}
412+
413+
type TypeB = {
414+
A: 'A',
415+
B: 'B',
416+
C: 'C',
417+
}
418+
419+
type R<T extends keyof TypeA> =
420+
T extends keyof TypeB ? [TypeA[T], TypeB[T]] : never;
421+
422+
type R2<T extends PropertyKey> =
423+
T extends keyof TypeA ? T extends keyof TypeB ? [TypeA[T], TypeB[T]] : never : never;
424+
425+
// Repro from #51041
426+
427+
type AB = "A" | "B";
428+
429+
function x<T_AB extends AB>(x: T_AB & undefined, y: any) {
430+
let r2: never = y as T_AB & undefined;
431+
}

0 commit comments

Comments
 (0)