Fix higher order inference on indexed access types (#20165)
This commit is contained in:
parent
00450f029c
commit
7ad0d7b9fd
|
@ -11400,7 +11400,7 @@ namespace ts {
|
|||
return;
|
||||
}
|
||||
}
|
||||
else if (getObjectFlags(source) & ObjectFlags.Reference && getObjectFlags(target) & ObjectFlags.Reference && (<TypeReference>source).target === (<TypeReference>target).target) {
|
||||
if (getObjectFlags(source) & ObjectFlags.Reference && getObjectFlags(target) & ObjectFlags.Reference && (<TypeReference>source).target === (<TypeReference>target).target) {
|
||||
// If source and target are references to the same generic type, infer from type arguments
|
||||
const sourceTypes = (<TypeReference>source).typeArguments || emptyArray;
|
||||
const targetTypes = (<TypeReference>target).typeArguments || emptyArray;
|
||||
|
|
21
tests/baselines/reference/indexedAccessCanBeHighOrder.js
Normal file
21
tests/baselines/reference/indexedAccessCanBeHighOrder.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
//// [indexedAccessCanBeHighOrder.ts]
|
||||
declare function get<U, Y extends keyof U>(x: U, y: Y): U[Y];
|
||||
declare function find<T, K extends keyof T>(o: T[K]): [T, K];
|
||||
|
||||
function impl<A, B extends keyof A>(a: A, b: B) {
|
||||
const item = get(a, b);
|
||||
return find(item);
|
||||
}
|
||||
|
||||
const o = {x: 42};
|
||||
const r = impl(o, "x");
|
||||
r[0][r[1]] = o[r[1]];
|
||||
|
||||
//// [indexedAccessCanBeHighOrder.js]
|
||||
function impl(a, b) {
|
||||
var item = get(a, b);
|
||||
return find(item);
|
||||
}
|
||||
var o = { x: 42 };
|
||||
var r = impl(o, "x");
|
||||
r[0][r[1]] = o[r[1]];
|
|
@ -0,0 +1,63 @@
|
|||
=== tests/cases/compiler/indexedAccessCanBeHighOrder.ts ===
|
||||
declare function get<U, Y extends keyof U>(x: U, y: Y): U[Y];
|
||||
>get : Symbol(get, Decl(indexedAccessCanBeHighOrder.ts, 0, 0))
|
||||
>U : Symbol(U, Decl(indexedAccessCanBeHighOrder.ts, 0, 21))
|
||||
>Y : Symbol(Y, Decl(indexedAccessCanBeHighOrder.ts, 0, 23))
|
||||
>U : Symbol(U, Decl(indexedAccessCanBeHighOrder.ts, 0, 21))
|
||||
>x : Symbol(x, Decl(indexedAccessCanBeHighOrder.ts, 0, 43))
|
||||
>U : Symbol(U, Decl(indexedAccessCanBeHighOrder.ts, 0, 21))
|
||||
>y : Symbol(y, Decl(indexedAccessCanBeHighOrder.ts, 0, 48))
|
||||
>Y : Symbol(Y, Decl(indexedAccessCanBeHighOrder.ts, 0, 23))
|
||||
>U : Symbol(U, Decl(indexedAccessCanBeHighOrder.ts, 0, 21))
|
||||
>Y : Symbol(Y, Decl(indexedAccessCanBeHighOrder.ts, 0, 23))
|
||||
|
||||
declare function find<T, K extends keyof T>(o: T[K]): [T, K];
|
||||
>find : Symbol(find, Decl(indexedAccessCanBeHighOrder.ts, 0, 61))
|
||||
>T : Symbol(T, Decl(indexedAccessCanBeHighOrder.ts, 1, 22))
|
||||
>K : Symbol(K, Decl(indexedAccessCanBeHighOrder.ts, 1, 24))
|
||||
>T : Symbol(T, Decl(indexedAccessCanBeHighOrder.ts, 1, 22))
|
||||
>o : Symbol(o, Decl(indexedAccessCanBeHighOrder.ts, 1, 44))
|
||||
>T : Symbol(T, Decl(indexedAccessCanBeHighOrder.ts, 1, 22))
|
||||
>K : Symbol(K, Decl(indexedAccessCanBeHighOrder.ts, 1, 24))
|
||||
>T : Symbol(T, Decl(indexedAccessCanBeHighOrder.ts, 1, 22))
|
||||
>K : Symbol(K, Decl(indexedAccessCanBeHighOrder.ts, 1, 24))
|
||||
|
||||
function impl<A, B extends keyof A>(a: A, b: B) {
|
||||
>impl : Symbol(impl, Decl(indexedAccessCanBeHighOrder.ts, 1, 61))
|
||||
>A : Symbol(A, Decl(indexedAccessCanBeHighOrder.ts, 3, 14))
|
||||
>B : Symbol(B, Decl(indexedAccessCanBeHighOrder.ts, 3, 16))
|
||||
>A : Symbol(A, Decl(indexedAccessCanBeHighOrder.ts, 3, 14))
|
||||
>a : Symbol(a, Decl(indexedAccessCanBeHighOrder.ts, 3, 36))
|
||||
>A : Symbol(A, Decl(indexedAccessCanBeHighOrder.ts, 3, 14))
|
||||
>b : Symbol(b, Decl(indexedAccessCanBeHighOrder.ts, 3, 41))
|
||||
>B : Symbol(B, Decl(indexedAccessCanBeHighOrder.ts, 3, 16))
|
||||
|
||||
const item = get(a, b);
|
||||
>item : Symbol(item, Decl(indexedAccessCanBeHighOrder.ts, 4, 9))
|
||||
>get : Symbol(get, Decl(indexedAccessCanBeHighOrder.ts, 0, 0))
|
||||
>a : Symbol(a, Decl(indexedAccessCanBeHighOrder.ts, 3, 36))
|
||||
>b : Symbol(b, Decl(indexedAccessCanBeHighOrder.ts, 3, 41))
|
||||
|
||||
return find(item);
|
||||
>find : Symbol(find, Decl(indexedAccessCanBeHighOrder.ts, 0, 61))
|
||||
>item : Symbol(item, Decl(indexedAccessCanBeHighOrder.ts, 4, 9))
|
||||
}
|
||||
|
||||
const o = {x: 42};
|
||||
>o : Symbol(o, Decl(indexedAccessCanBeHighOrder.ts, 8, 5))
|
||||
>x : Symbol(x, Decl(indexedAccessCanBeHighOrder.ts, 8, 11))
|
||||
|
||||
const r = impl(o, "x");
|
||||
>r : Symbol(r, Decl(indexedAccessCanBeHighOrder.ts, 9, 5))
|
||||
>impl : Symbol(impl, Decl(indexedAccessCanBeHighOrder.ts, 1, 61))
|
||||
>o : Symbol(o, Decl(indexedAccessCanBeHighOrder.ts, 8, 5))
|
||||
|
||||
r[0][r[1]] = o[r[1]];
|
||||
>r : Symbol(r, Decl(indexedAccessCanBeHighOrder.ts, 9, 5))
|
||||
>0 : Symbol(0)
|
||||
>r : Symbol(r, Decl(indexedAccessCanBeHighOrder.ts, 9, 5))
|
||||
>1 : Symbol(1)
|
||||
>o : Symbol(o, Decl(indexedAccessCanBeHighOrder.ts, 8, 5))
|
||||
>r : Symbol(r, Decl(indexedAccessCanBeHighOrder.ts, 9, 5))
|
||||
>1 : Symbol(1)
|
||||
|
75
tests/baselines/reference/indexedAccessCanBeHighOrder.types
Normal file
75
tests/baselines/reference/indexedAccessCanBeHighOrder.types
Normal file
|
@ -0,0 +1,75 @@
|
|||
=== tests/cases/compiler/indexedAccessCanBeHighOrder.ts ===
|
||||
declare function get<U, Y extends keyof U>(x: U, y: Y): U[Y];
|
||||
>get : <U, Y extends keyof U>(x: U, y: Y) => U[Y]
|
||||
>U : U
|
||||
>Y : Y
|
||||
>U : U
|
||||
>x : U
|
||||
>U : U
|
||||
>y : Y
|
||||
>Y : Y
|
||||
>U : U
|
||||
>Y : Y
|
||||
|
||||
declare function find<T, K extends keyof T>(o: T[K]): [T, K];
|
||||
>find : <T, K extends keyof T>(o: T[K]) => [T, K]
|
||||
>T : T
|
||||
>K : K
|
||||
>T : T
|
||||
>o : T[K]
|
||||
>T : T
|
||||
>K : K
|
||||
>T : T
|
||||
>K : K
|
||||
|
||||
function impl<A, B extends keyof A>(a: A, b: B) {
|
||||
>impl : <A, B extends keyof A>(a: A, b: B) => [A, B]
|
||||
>A : A
|
||||
>B : B
|
||||
>A : A
|
||||
>a : A
|
||||
>A : A
|
||||
>b : B
|
||||
>B : B
|
||||
|
||||
const item = get(a, b);
|
||||
>item : A[B]
|
||||
>get(a, b) : A[B]
|
||||
>get : <U, Y extends keyof U>(x: U, y: Y) => U[Y]
|
||||
>a : A
|
||||
>b : B
|
||||
|
||||
return find(item);
|
||||
>find(item) : [A, B]
|
||||
>find : <T, K extends keyof T>(o: T[K]) => [T, K]
|
||||
>item : A[B]
|
||||
}
|
||||
|
||||
const o = {x: 42};
|
||||
>o : { x: number; }
|
||||
>{x: 42} : { x: number; }
|
||||
>x : number
|
||||
>42 : 42
|
||||
|
||||
const r = impl(o, "x");
|
||||
>r : [{ x: number; }, "x"]
|
||||
>impl(o, "x") : [{ x: number; }, "x"]
|
||||
>impl : <A, B extends keyof A>(a: A, b: B) => [A, B]
|
||||
>o : { x: number; }
|
||||
>"x" : "x"
|
||||
|
||||
r[0][r[1]] = o[r[1]];
|
||||
>r[0][r[1]] = o[r[1]] : number
|
||||
>r[0][r[1]] : number
|
||||
>r[0] : { x: number; }
|
||||
>r : [{ x: number; }, "x"]
|
||||
>0 : 0
|
||||
>r[1] : "x"
|
||||
>r : [{ x: number; }, "x"]
|
||||
>1 : 1
|
||||
>o[r[1]] : number
|
||||
>o : { x: number; }
|
||||
>r[1] : "x"
|
||||
>r : [{ x: number; }, "x"]
|
||||
>1 : 1
|
||||
|
11
tests/cases/compiler/indexedAccessCanBeHighOrder.ts
Normal file
11
tests/cases/compiler/indexedAccessCanBeHighOrder.ts
Normal file
|
@ -0,0 +1,11 @@
|
|||
declare function get<U, Y extends keyof U>(x: U, y: Y): U[Y];
|
||||
declare function find<T, K extends keyof T>(o: T[K]): [T, K];
|
||||
|
||||
function impl<A, B extends keyof A>(a: A, b: B) {
|
||||
const item = get(a, b);
|
||||
return find(item);
|
||||
}
|
||||
|
||||
const o = {x: 42};
|
||||
const r = impl(o, "x");
|
||||
r[0][r[1]] = o[r[1]];
|
Loading…
Reference in a new issue