Fix higher order inference on indexed access types (#20165)

This commit is contained in:
Wesley Wigham 2017-12-21 14:47:03 -08:00 committed by GitHub
parent 00450f029c
commit 7ad0d7b9fd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 171 additions and 1 deletions

View file

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

View 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]];

View file

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

View 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

View 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]];