Test assignability of indexed access types
This commit is contained in:
parent
5c889299f4
commit
485ec34e8e
9 changed files with 377 additions and 47 deletions
|
@ -552,6 +552,19 @@ class AnotherSampleClass<T> extends SampleClass<T & Foo> {
|
|||
}
|
||||
}
|
||||
new AnotherSampleClass({});
|
||||
|
||||
// Positive repro from #17166
|
||||
function f3<T, K extends keyof T>(t: T, k: K, tk: T[K]): void {
|
||||
for (let key in t) {
|
||||
key = k // ok, K ==> keyof T
|
||||
t[key] = tk; // ok, T[K] ==> T[keyof T]
|
||||
}
|
||||
}
|
||||
|
||||
// # 21185
|
||||
type Predicates<TaggedRecord> = {
|
||||
[T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T]
|
||||
}
|
||||
|
||||
|
||||
//// [keyofAndIndexedAccess.js]
|
||||
|
@ -928,6 +941,13 @@ var AnotherSampleClass = /** @class */ (function (_super) {
|
|||
return AnotherSampleClass;
|
||||
}(SampleClass));
|
||||
new AnotherSampleClass({});
|
||||
// Positive repro from #17166
|
||||
function f3(t, k, tk) {
|
||||
for (var key in t) {
|
||||
key = k; // ok, K ==> keyof T
|
||||
t[key] = tk; // ok, T[K] ==> T[keyof T]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// [keyofAndIndexedAccess.d.ts]
|
||||
|
@ -1188,3 +1208,7 @@ declare class AnotherSampleClass<T> extends SampleClass<T & Foo> {
|
|||
constructor(props: T);
|
||||
brokenMethod(): void;
|
||||
}
|
||||
declare function f3<T, K extends keyof T>(t: T, k: K, tk: T[K]): void;
|
||||
declare type Predicates<TaggedRecord> = {
|
||||
[T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T];
|
||||
};
|
||||
|
|
|
@ -1962,3 +1962,48 @@ class AnotherSampleClass<T> extends SampleClass<T & Foo> {
|
|||
new AnotherSampleClass({});
|
||||
>AnotherSampleClass : Symbol(AnotherSampleClass, Decl(keyofAndIndexedAccess.ts, 540, 54))
|
||||
|
||||
// Positive repro from #17166
|
||||
function f3<T, K extends keyof T>(t: T, k: K, tk: T[K]): void {
|
||||
>f3 : Symbol(f3, Decl(keyofAndIndexedAccess.ts, 552, 27))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 555, 12))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 555, 14))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 555, 12))
|
||||
>t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 555, 34))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 555, 12))
|
||||
>k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 555, 39))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 555, 14))
|
||||
>tk : Symbol(tk, Decl(keyofAndIndexedAccess.ts, 555, 45))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 555, 12))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccess.ts, 555, 14))
|
||||
|
||||
for (let key in t) {
|
||||
>key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 556, 12))
|
||||
>t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 555, 34))
|
||||
|
||||
key = k // ok, K ==> keyof T
|
||||
>key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 556, 12))
|
||||
>k : Symbol(k, Decl(keyofAndIndexedAccess.ts, 555, 39))
|
||||
|
||||
t[key] = tk; // ok, T[K] ==> T[keyof T]
|
||||
>t : Symbol(t, Decl(keyofAndIndexedAccess.ts, 555, 34))
|
||||
>key : Symbol(key, Decl(keyofAndIndexedAccess.ts, 556, 12))
|
||||
>tk : Symbol(tk, Decl(keyofAndIndexedAccess.ts, 555, 45))
|
||||
}
|
||||
}
|
||||
|
||||
// # 21185
|
||||
type Predicates<TaggedRecord> = {
|
||||
>Predicates : Symbol(Predicates, Decl(keyofAndIndexedAccess.ts, 560, 1))
|
||||
>TaggedRecord : Symbol(TaggedRecord, Decl(keyofAndIndexedAccess.ts, 563, 16))
|
||||
|
||||
[T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T]
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 564, 3))
|
||||
>TaggedRecord : Symbol(TaggedRecord, Decl(keyofAndIndexedAccess.ts, 563, 16))
|
||||
>variant : Symbol(variant, Decl(keyofAndIndexedAccess.ts, 564, 30))
|
||||
>TaggedRecord : Symbol(TaggedRecord, Decl(keyofAndIndexedAccess.ts, 563, 16))
|
||||
>TaggedRecord : Symbol(TaggedRecord, Decl(keyofAndIndexedAccess.ts, 563, 16))
|
||||
>variant : Symbol(variant, Decl(keyofAndIndexedAccess.ts, 564, 30))
|
||||
>TaggedRecord : Symbol(TaggedRecord, Decl(keyofAndIndexedAccess.ts, 563, 16))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccess.ts, 564, 3))
|
||||
}
|
||||
|
||||
|
|
|
@ -2294,3 +2294,51 @@ new AnotherSampleClass({});
|
|||
>AnotherSampleClass : typeof AnotherSampleClass
|
||||
>{} : {}
|
||||
|
||||
// Positive repro from #17166
|
||||
function f3<T, K extends keyof T>(t: T, k: K, tk: T[K]): void {
|
||||
>f3 : <T, K extends keyof T>(t: T, k: K, tk: T[K]) => void
|
||||
>T : T
|
||||
>K : K
|
||||
>T : T
|
||||
>t : T
|
||||
>T : T
|
||||
>k : K
|
||||
>K : K
|
||||
>tk : T[K]
|
||||
>T : T
|
||||
>K : K
|
||||
|
||||
for (let key in t) {
|
||||
>key : keyof T
|
||||
>t : T
|
||||
|
||||
key = k // ok, K ==> keyof T
|
||||
>key = k : K
|
||||
>key : keyof T
|
||||
>k : K
|
||||
|
||||
t[key] = tk; // ok, T[K] ==> T[keyof T]
|
||||
>t[key] = tk : T[K]
|
||||
>t[key] : T[keyof T]
|
||||
>t : T
|
||||
>key : keyof T
|
||||
>tk : T[K]
|
||||
}
|
||||
}
|
||||
|
||||
// # 21185
|
||||
type Predicates<TaggedRecord> = {
|
||||
>Predicates : Predicates<TaggedRecord>
|
||||
>TaggedRecord : TaggedRecord
|
||||
|
||||
[T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T]
|
||||
>T : T
|
||||
>TaggedRecord : TaggedRecord
|
||||
>variant : TaggedRecord[keyof TaggedRecord]
|
||||
>TaggedRecord : TaggedRecord
|
||||
>TaggedRecord : TaggedRecord
|
||||
>variant : any
|
||||
>TaggedRecord : TaggedRecord
|
||||
>T : T
|
||||
}
|
||||
|
||||
|
|
|
@ -27,11 +27,21 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(76,5): error
|
|||
Type 'T' is not assignable to type 'T & U'.
|
||||
Type 'T' is not assignable to type 'U'.
|
||||
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(77,5): error TS2322: Type 'keyof (T & U)' is not assignable to type 'keyof (T | U)'.
|
||||
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(84,9): error TS2322: Type 'keyof T' is not assignable to type 'K'.
|
||||
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(85,9): error TS2322: Type 'T[keyof T]' is not assignable to type 'T[K]'.
|
||||
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(86,9): error TS2322: Type 'keyof T' is not assignable to type 'K'.
|
||||
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(88,9): error TS2322: Type 'T[keyof T]' is not assignable to type 'T[K]'.
|
||||
Type 'keyof T' is not assignable to type 'K'.
|
||||
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(91,5): error TS2322: Type 'T[K]' is not assignable to type 'U[K]'.
|
||||
Type 'T' is not assignable to type 'U'.
|
||||
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(94,5): error TS2322: Type 'T[J]' is not assignable to type 'U[J]'.
|
||||
Type 'T' is not assignable to type 'U'.
|
||||
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(97,5): error TS2322: Type 'T[K]' is not assignable to type 'T[J]'.
|
||||
Type 'K' is not assignable to type 'J'.
|
||||
Type 'keyof T' is not assignable to type 'J'.
|
||||
tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(100,5): error TS2322: Type 'T[K]' is not assignable to type 'U[J]'.
|
||||
Type 'T' is not assignable to type 'U'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts (27 errors) ====
|
||||
==== tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts (31 errors) ====
|
||||
class Shape {
|
||||
name: string;
|
||||
width: number;
|
||||
|
@ -167,15 +177,42 @@ tests/cases/conformance/types/keyof/keyofAndIndexedAccessErrors.ts(85,9): error
|
|||
}
|
||||
|
||||
// Repro from #17166
|
||||
function f3<T, K extends keyof T>(obj: T, k: K, value: T[K]): void {
|
||||
for (let key in obj) {
|
||||
function f3<T, K extends keyof T, U extends T, J extends K>(
|
||||
t: T, k: K, tk: T[K], u: U, j: J, uk: U[K], tj: T[J], uj: U[J]): void {
|
||||
for (let key in t) {
|
||||
key = k // ok, K ==> keyof T
|
||||
k = key // error, keyof T =/=> K
|
||||
~
|
||||
!!! error TS2322: Type 'keyof T' is not assignable to type 'K'.
|
||||
value = obj[key]; // error, T[keyof T] =/=> T[K]
|
||||
~~~~~
|
||||
t[key] = tk; // ok, T[K] ==> T[keyof T]
|
||||
tk = t[key]; // error, T[keyof T] =/=> T[K]
|
||||
~~
|
||||
!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'T[K]'.
|
||||
!!! error TS2322: Type 'keyof T' is not assignable to type 'K'.
|
||||
}
|
||||
}
|
||||
tk = uk;
|
||||
uk = tk; // error
|
||||
~~
|
||||
!!! error TS2322: Type 'T[K]' is not assignable to type 'U[K]'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'U'.
|
||||
|
||||
tj = uj;
|
||||
uj = tj; // error
|
||||
~~
|
||||
!!! error TS2322: Type 'T[J]' is not assignable to type 'U[J]'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'U'.
|
||||
|
||||
tk = tj;
|
||||
tj = tk; // error
|
||||
~~
|
||||
!!! error TS2322: Type 'T[K]' is not assignable to type 'T[J]'.
|
||||
!!! error TS2322: Type 'K' is not assignable to type 'J'.
|
||||
!!! error TS2322: Type 'keyof T' is not assignable to type 'J'.
|
||||
|
||||
tk = uj;
|
||||
uj = tk; // error
|
||||
~~
|
||||
!!! error TS2322: Type 'T[K]' is not assignable to type 'U[J]'.
|
||||
!!! error TS2322: Type 'T' is not assignable to type 'U'.
|
||||
}
|
||||
|
|
@ -80,13 +80,26 @@ function f20<T, U>(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) {
|
|||
}
|
||||
|
||||
// Repro from #17166
|
||||
function f3<T, K extends keyof T>(obj: T, k: K, value: T[K]): void {
|
||||
for (let key in obj) {
|
||||
function f3<T, K extends keyof T, U extends T, J extends K>(
|
||||
t: T, k: K, tk: T[K], u: U, j: J, uk: U[K], tj: T[J], uj: U[J]): void {
|
||||
for (let key in t) {
|
||||
key = k // ok, K ==> keyof T
|
||||
k = key // error, keyof T =/=> K
|
||||
value = obj[key]; // error, T[keyof T] =/=> T[K]
|
||||
t[key] = tk; // ok, T[K] ==> T[keyof T]
|
||||
tk = t[key]; // error, T[keyof T] =/=> T[K]
|
||||
}
|
||||
}
|
||||
tk = uk;
|
||||
uk = tk; // error
|
||||
|
||||
tj = uj;
|
||||
uj = tj; // error
|
||||
|
||||
tk = tj;
|
||||
tj = tk; // error
|
||||
|
||||
tk = uj;
|
||||
uj = tk; // error
|
||||
}
|
||||
|
||||
|
||||
//// [keyofAndIndexedAccessErrors.js]
|
||||
|
@ -120,9 +133,19 @@ function f20(k1, k2, o1, o2) {
|
|||
k2 = k1;
|
||||
}
|
||||
// Repro from #17166
|
||||
function f3(obj, k, value) {
|
||||
for (var key in obj) {
|
||||
function f3(t, k, tk, u, j, uk, tj, uj) {
|
||||
for (var key in t) {
|
||||
key = k; // ok, K ==> keyof T
|
||||
k = key; // error, keyof T =/=> K
|
||||
value = obj[key]; // error, T[keyof T] =/=> T[K]
|
||||
t[key] = tk; // ok, T[K] ==> T[keyof T]
|
||||
tk = t[key]; // error, T[keyof T] =/=> T[K]
|
||||
}
|
||||
tk = uk;
|
||||
uk = tk; // error
|
||||
tj = uj;
|
||||
uj = tj; // error
|
||||
tk = tj;
|
||||
tj = tk; // error
|
||||
tk = uj;
|
||||
uj = tk; // error
|
||||
}
|
||||
|
|
|
@ -270,32 +270,90 @@ function f20<T, U>(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) {
|
|||
}
|
||||
|
||||
// Repro from #17166
|
||||
function f3<T, K extends keyof T>(obj: T, k: K, value: T[K]): void {
|
||||
function f3<T, K extends keyof T, U extends T, J extends K>(
|
||||
>f3 : Symbol(f3, Decl(keyofAndIndexedAccessErrors.ts, 78, 1))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12))
|
||||
>obj : Symbol(obj, Decl(keyofAndIndexedAccessErrors.ts, 81, 34))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12))
|
||||
>k : Symbol(k, Decl(keyofAndIndexedAccessErrors.ts, 81, 41))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14))
|
||||
>value : Symbol(value, Decl(keyofAndIndexedAccessErrors.ts, 81, 47))
|
||||
>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 81, 33))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12))
|
||||
>J : Symbol(J, Decl(keyofAndIndexedAccessErrors.ts, 81, 46))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14))
|
||||
|
||||
for (let key in obj) {
|
||||
>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 82, 12))
|
||||
>obj : Symbol(obj, Decl(keyofAndIndexedAccessErrors.ts, 81, 34))
|
||||
t: T, k: K, tk: T[K], u: U, j: J, uk: U[K], tj: T[J], uj: U[J]): void {
|
||||
>t : Symbol(t, Decl(keyofAndIndexedAccessErrors.ts, 81, 60))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12))
|
||||
>k : Symbol(k, Decl(keyofAndIndexedAccessErrors.ts, 82, 9))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14))
|
||||
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14))
|
||||
>u : Symbol(u, Decl(keyofAndIndexedAccessErrors.ts, 82, 25))
|
||||
>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 81, 33))
|
||||
>j : Symbol(j, Decl(keyofAndIndexedAccessErrors.ts, 82, 31))
|
||||
>J : Symbol(J, Decl(keyofAndIndexedAccessErrors.ts, 81, 46))
|
||||
>uk : Symbol(uk, Decl(keyofAndIndexedAccessErrors.ts, 82, 37))
|
||||
>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 81, 33))
|
||||
>K : Symbol(K, Decl(keyofAndIndexedAccessErrors.ts, 81, 14))
|
||||
>tj : Symbol(tj, Decl(keyofAndIndexedAccessErrors.ts, 82, 47))
|
||||
>T : Symbol(T, Decl(keyofAndIndexedAccessErrors.ts, 81, 12))
|
||||
>J : Symbol(J, Decl(keyofAndIndexedAccessErrors.ts, 81, 46))
|
||||
>uj : Symbol(uj, Decl(keyofAndIndexedAccessErrors.ts, 82, 57))
|
||||
>U : Symbol(U, Decl(keyofAndIndexedAccessErrors.ts, 81, 33))
|
||||
>J : Symbol(J, Decl(keyofAndIndexedAccessErrors.ts, 81, 46))
|
||||
|
||||
for (let key in t) {
|
||||
>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 83, 12))
|
||||
>t : Symbol(t, Decl(keyofAndIndexedAccessErrors.ts, 81, 60))
|
||||
|
||||
key = k // ok, K ==> keyof T
|
||||
>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 83, 12))
|
||||
>k : Symbol(k, Decl(keyofAndIndexedAccessErrors.ts, 82, 9))
|
||||
|
||||
k = key // error, keyof T =/=> K
|
||||
>k : Symbol(k, Decl(keyofAndIndexedAccessErrors.ts, 81, 41))
|
||||
>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 82, 12))
|
||||
>k : Symbol(k, Decl(keyofAndIndexedAccessErrors.ts, 82, 9))
|
||||
>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 83, 12))
|
||||
|
||||
value = obj[key]; // error, T[keyof T] =/=> T[K]
|
||||
>value : Symbol(value, Decl(keyofAndIndexedAccessErrors.ts, 81, 47))
|
||||
>obj : Symbol(obj, Decl(keyofAndIndexedAccessErrors.ts, 81, 34))
|
||||
>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 82, 12))
|
||||
t[key] = tk; // ok, T[K] ==> T[keyof T]
|
||||
>t : Symbol(t, Decl(keyofAndIndexedAccessErrors.ts, 81, 60))
|
||||
>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 83, 12))
|
||||
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15))
|
||||
|
||||
tk = t[key]; // error, T[keyof T] =/=> T[K]
|
||||
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15))
|
||||
>t : Symbol(t, Decl(keyofAndIndexedAccessErrors.ts, 81, 60))
|
||||
>key : Symbol(key, Decl(keyofAndIndexedAccessErrors.ts, 83, 12))
|
||||
}
|
||||
tk = uk;
|
||||
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15))
|
||||
>uk : Symbol(uk, Decl(keyofAndIndexedAccessErrors.ts, 82, 37))
|
||||
|
||||
uk = tk; // error
|
||||
>uk : Symbol(uk, Decl(keyofAndIndexedAccessErrors.ts, 82, 37))
|
||||
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15))
|
||||
|
||||
tj = uj;
|
||||
>tj : Symbol(tj, Decl(keyofAndIndexedAccessErrors.ts, 82, 47))
|
||||
>uj : Symbol(uj, Decl(keyofAndIndexedAccessErrors.ts, 82, 57))
|
||||
|
||||
uj = tj; // error
|
||||
>uj : Symbol(uj, Decl(keyofAndIndexedAccessErrors.ts, 82, 57))
|
||||
>tj : Symbol(tj, Decl(keyofAndIndexedAccessErrors.ts, 82, 47))
|
||||
|
||||
tk = tj;
|
||||
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15))
|
||||
>tj : Symbol(tj, Decl(keyofAndIndexedAccessErrors.ts, 82, 47))
|
||||
|
||||
tj = tk; // error
|
||||
>tj : Symbol(tj, Decl(keyofAndIndexedAccessErrors.ts, 82, 47))
|
||||
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15))
|
||||
|
||||
tk = uj;
|
||||
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15))
|
||||
>uj : Symbol(uj, Decl(keyofAndIndexedAccessErrors.ts, 82, 57))
|
||||
|
||||
uj = tk; // error
|
||||
>uj : Symbol(uj, Decl(keyofAndIndexedAccessErrors.ts, 82, 57))
|
||||
>tk : Symbol(tk, Decl(keyofAndIndexedAccessErrors.ts, 82, 15))
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -301,35 +301,104 @@ function f20<T, U>(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) {
|
|||
}
|
||||
|
||||
// Repro from #17166
|
||||
function f3<T, K extends keyof T>(obj: T, k: K, value: T[K]): void {
|
||||
>f3 : <T, K extends keyof T>(obj: T, k: K, value: T[K]) => void
|
||||
function f3<T, K extends keyof T, U extends T, J extends K>(
|
||||
>f3 : <T, K extends keyof T, U extends T, J extends K>(t: T, k: K, tk: T[K], u: U, j: J, uk: U[K], tj: T[J], uj: U[J]) => void
|
||||
>T : T
|
||||
>K : K
|
||||
>T : T
|
||||
>obj : T
|
||||
>U : U
|
||||
>T : T
|
||||
>J : J
|
||||
>K : K
|
||||
|
||||
t: T, k: K, tk: T[K], u: U, j: J, uk: U[K], tj: T[J], uj: U[J]): void {
|
||||
>t : T
|
||||
>T : T
|
||||
>k : K
|
||||
>K : K
|
||||
>value : T[K]
|
||||
>tk : T[K]
|
||||
>T : T
|
||||
>K : K
|
||||
>u : U
|
||||
>U : U
|
||||
>j : J
|
||||
>J : J
|
||||
>uk : U[K]
|
||||
>U : U
|
||||
>K : K
|
||||
>tj : T[J]
|
||||
>T : T
|
||||
>J : J
|
||||
>uj : U[J]
|
||||
>U : U
|
||||
>J : J
|
||||
|
||||
for (let key in obj) {
|
||||
for (let key in t) {
|
||||
>key : keyof T
|
||||
>obj : T
|
||||
>t : T
|
||||
|
||||
key = k // ok, K ==> keyof T
|
||||
>key = k : K
|
||||
>key : keyof T
|
||||
>k : K
|
||||
|
||||
k = key // error, keyof T =/=> K
|
||||
>k = key : keyof T
|
||||
>k : K
|
||||
>key : keyof T
|
||||
|
||||
value = obj[key]; // error, T[keyof T] =/=> T[K]
|
||||
>value = obj[key] : T[keyof T]
|
||||
>value : T[K]
|
||||
>obj[key] : T[keyof T]
|
||||
>obj : T
|
||||
t[key] = tk; // ok, T[K] ==> T[keyof T]
|
||||
>t[key] = tk : T[K]
|
||||
>t[key] : T[keyof T]
|
||||
>t : T
|
||||
>key : keyof T
|
||||
>tk : T[K]
|
||||
|
||||
tk = t[key]; // error, T[keyof T] =/=> T[K]
|
||||
>tk = t[key] : T[keyof T]
|
||||
>tk : T[K]
|
||||
>t[key] : T[keyof T]
|
||||
>t : T
|
||||
>key : keyof T
|
||||
}
|
||||
tk = uk;
|
||||
>tk = uk : U[K]
|
||||
>tk : T[K]
|
||||
>uk : U[K]
|
||||
|
||||
uk = tk; // error
|
||||
>uk = tk : T[K]
|
||||
>uk : U[K]
|
||||
>tk : T[K]
|
||||
|
||||
tj = uj;
|
||||
>tj = uj : U[J]
|
||||
>tj : T[J]
|
||||
>uj : U[J]
|
||||
|
||||
uj = tj; // error
|
||||
>uj = tj : T[J]
|
||||
>uj : U[J]
|
||||
>tj : T[J]
|
||||
|
||||
tk = tj;
|
||||
>tk = tj : T[J]
|
||||
>tk : T[K]
|
||||
>tj : T[J]
|
||||
|
||||
tj = tk; // error
|
||||
>tj = tk : T[K]
|
||||
>tj : T[J]
|
||||
>tk : T[K]
|
||||
|
||||
tk = uj;
|
||||
>tk = uj : U[J]
|
||||
>tk : T[K]
|
||||
>uj : U[J]
|
||||
|
||||
uj = tk; // error
|
||||
>uj = tk : T[K]
|
||||
>uj : U[J]
|
||||
>tk : T[K]
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -554,3 +554,16 @@ class AnotherSampleClass<T> extends SampleClass<T & Foo> {
|
|||
}
|
||||
}
|
||||
new AnotherSampleClass({});
|
||||
|
||||
// Positive repro from #17166
|
||||
function f3<T, K extends keyof T>(t: T, k: K, tk: T[K]): void {
|
||||
for (let key in t) {
|
||||
key = k // ok, K ==> keyof T
|
||||
t[key] = tk; // ok, T[K] ==> T[keyof T]
|
||||
}
|
||||
}
|
||||
|
||||
// # 21185
|
||||
type Predicates<TaggedRecord> = {
|
||||
[T in keyof TaggedRecord]: (variant: TaggedRecord[keyof TaggedRecord]) => variant is TaggedRecord[T]
|
||||
}
|
||||
|
|
|
@ -79,10 +79,23 @@ function f20<T, U>(k1: keyof (T | U), k2: keyof (T & U), o1: T | U, o2: T & U) {
|
|||
}
|
||||
|
||||
// Repro from #17166
|
||||
function f3<T, K extends keyof T>(obj: T, k: K, value: T[K]): void {
|
||||
for (let key in obj) {
|
||||
function f3<T, K extends keyof T, U extends T, J extends K>(
|
||||
t: T, k: K, tk: T[K], u: U, j: J, uk: U[K], tj: T[J], uj: U[J]): void {
|
||||
for (let key in t) {
|
||||
key = k // ok, K ==> keyof T
|
||||
k = key // error, keyof T =/=> K
|
||||
value = obj[key]; // error, T[keyof T] =/=> T[K]
|
||||
t[key] = tk; // ok, T[K] ==> T[keyof T]
|
||||
tk = t[key]; // error, T[keyof T] =/=> T[K]
|
||||
}
|
||||
}
|
||||
tk = uk;
|
||||
uk = tk; // error
|
||||
|
||||
tj = uj;
|
||||
uj = tj; // error
|
||||
|
||||
tk = tj;
|
||||
tj = tk; // error
|
||||
|
||||
tk = uj;
|
||||
uj = tk; // error
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue