Do not mark indexed access object type comparisons as unreliable. (#54781)

This commit is contained in:
Daniel Rosenwasser 2023-06-26 13:21:10 -07:00 committed by GitHub
parent 4cac28ed57
commit f762de5220
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 6 deletions

View File

@ -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) {

View File

@ -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;

View File

@ -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