Skip to content

Commit

Permalink
Do not mark indexed access object type comparisons as unreliable.
Browse files Browse the repository at this point in the history
  • Loading branch information
DanielRosenwasser committed Jun 26, 2023
1 parent a94eb31 commit 8d94382
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 6 deletions.
5 changes: 0 additions & 5 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21538,11 +21538,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
// Relate components directly before falling back to constraint relationships
// A type S[K] is related to a type T[J] if S is related to T and K is related to J.
if (result = isRelatedTo((source as IndexedAccessType).objectType, (target as IndexedAccessType).objectType, RecursionFlags.Both, reportErrors)) {
// This does _not_ generalize - specific instantiations of `S[K]` and `T[J]` may be related, even if the indexed accesses generally are not.
// For example, `S = {x: string, a: string}`, `T = {x: string, b: string}`, `K = J = "x"`. `S` and `T` are unrelated, but the result of executing
// `S["x"]` and `T["x"]` _are_. Given that, we have to flag the object type comparison here as "unreliable", since while the generic result can reliably
// be used in the affirmative case, it failing is not an indicator that the structural result will not succeed.
instantiateType((source as IndexedAccessType).objectType, reportUnreliableMapper);
result &= isRelatedTo((source as IndexedAccessType).indexType, (target as IndexedAccessType).indexType, RecursionFlags.Both, reportErrors);
}
if (result) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
genericIndexedAccessVarianceComparisonResultCorrect.ts(25,1): error TS2322: Type 'T<A>' is not assignable to type 'T<B>'.
Property 'z' is missing in type 'A' but required in type 'B'.


==== genericIndexedAccessVarianceComparisonResultCorrect.ts (1 errors) ====
class A {
x: string = 'A';
y: number = 0;
}

class B {
x: string = 'B';
z: boolean = true;
}

type T<X extends { x: any }> = Pick<X, 'x'>;

type C = T<A>;
type D = T<B>;

type C_extends_D = C extends D ? true : false; // true
type PickA_extends_PickB = Pick<A, 'x'> extends Pick<B, 'x'> ? true : false; // true
type TA_extends_TB = T<A> extends T<B> ? true : false; // should be true

declare let a: T<A>;
declare let b: T<B>;
declare let c: C;
declare let d: D;

b = a; // should be no error
~
!!! error TS2322: Type 'T<A>' is not assignable to type 'T<B>'.
!!! error TS2322: Property 'z' is missing in type 'A' but required in type 'B'.
!!! related TS2728 genericIndexedAccessVarianceComparisonResultCorrect.ts:8:5: 'z' is declared here.
c = d;
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ type PickA_extends_PickB = Pick<A, 'x'> extends Pick<B, 'x'> ? true : false;
>false : false

type TA_extends_TB = T<A> extends T<B> ? true : false; // should be true
>TA_extends_TB : true
>TA_extends_TB : false
>true : true
>false : false

Expand Down

0 comments on commit 8d94382

Please sign in to comment.