Skip to content

Commit 90f2ef8

Browse files
committed
Relate sources to base constraints of mapped type generic indexed accesses
1 parent 8c62e08 commit 90f2ef8

7 files changed

Lines changed: 549 additions & 3 deletions

File tree

src/compiler/checker.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23515,9 +23515,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2351523515
const baseObjectType = getBaseConstraintOfType(objectType) || objectType;
2351623516
const baseIndexType = getBaseConstraintOfType(indexType) || indexType;
2351723517
if (!isGenericObjectType(baseObjectType) && !isGenericIndexType(baseIndexType)) {
23518-
const accessFlags = AccessFlags.Writing | (baseObjectType !== objectType ? AccessFlags.NoIndexSignatures : 0);
23519-
const constraint = getIndexedAccessTypeOrUndefined(baseObjectType, baseIndexType, accessFlags);
23520-
if (constraint) {
23518+
let constraint;
23519+
if (
23520+
isMappedTypeGenericIndexedAccess(target) &&
23521+
(constraint = getBaseConstraintOfType(target)) &&
23522+
(result = isRelatedTo(source, constraint, RecursionFlags.Target, /*reportErrors*/ false, /*headMessage*/ undefined, intersectionState))
23523+
) {
23524+
return result;
23525+
}
23526+
if (constraint = getIndexedAccessTypeOrUndefined(baseObjectType, baseIndexType, AccessFlags.Writing | (baseObjectType !== objectType ? AccessFlags.NoIndexSignatures : 0))) {
2352123527
if (reportErrors && originalErrorInfo) {
2352223528
// create a new chain for the constraint error
2352323529
resetErrorInfo(saveErrorInfo);
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
//// [tests/cases/compiler/correlatedUnions2.ts] ////
2+
3+
=== correlatedUnions2.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/61676
5+
6+
type Definitions = {
7+
>Definitions : Symbol(Definitions, Decl(correlatedUnions2.ts, 0, 0))
8+
9+
onFoo: [arg: number];
10+
>onFoo : Symbol(onFoo, Decl(correlatedUnions2.ts, 2, 20))
11+
12+
onBar: [arg: string];
13+
>onBar : Symbol(onBar, Decl(correlatedUnions2.ts, 3, 23))
14+
15+
};
16+
17+
type SomeCallbacks = {
18+
>SomeCallbacks : Symbol(SomeCallbacks, Decl(correlatedUnions2.ts, 5, 2))
19+
20+
[K in keyof Definitions]: (...args: Definitions[K]) => void;
21+
>K : Symbol(K, Decl(correlatedUnions2.ts, 8, 3))
22+
>Definitions : Symbol(Definitions, Decl(correlatedUnions2.ts, 0, 0))
23+
>args : Symbol(args, Decl(correlatedUnions2.ts, 8, 29))
24+
>Definitions : Symbol(Definitions, Decl(correlatedUnions2.ts, 0, 0))
25+
>K : Symbol(K, Decl(correlatedUnions2.ts, 8, 3))
26+
27+
};
28+
29+
const wrapCallback = <K extends keyof SomeCallbacks>(
30+
>wrapCallback : Symbol(wrapCallback, Decl(correlatedUnions2.ts, 11, 5))
31+
>K : Symbol(K, Decl(correlatedUnions2.ts, 11, 22))
32+
>SomeCallbacks : Symbol(SomeCallbacks, Decl(correlatedUnions2.ts, 5, 2))
33+
34+
source: SomeCallbacks,
35+
>source : Symbol(source, Decl(correlatedUnions2.ts, 11, 53))
36+
>SomeCallbacks : Symbol(SomeCallbacks, Decl(correlatedUnions2.ts, 5, 2))
37+
38+
target: SomeCallbacks,
39+
>target : Symbol(target, Decl(correlatedUnions2.ts, 12, 24))
40+
>SomeCallbacks : Symbol(SomeCallbacks, Decl(correlatedUnions2.ts, 5, 2))
41+
42+
key: K,
43+
>key : Symbol(key, Decl(correlatedUnions2.ts, 13, 24))
44+
>K : Symbol(K, Decl(correlatedUnions2.ts, 11, 22))
45+
46+
) => {
47+
const callback = source[key];
48+
>callback : Symbol(callback, Decl(correlatedUnions2.ts, 16, 7))
49+
>source : Symbol(source, Decl(correlatedUnions2.ts, 11, 53))
50+
>key : Symbol(key, Decl(correlatedUnions2.ts, 13, 24))
51+
52+
target[key] = (...args) => {
53+
>target : Symbol(target, Decl(correlatedUnions2.ts, 12, 24))
54+
>key : Symbol(key, Decl(correlatedUnions2.ts, 13, 24))
55+
>args : Symbol(args, Decl(correlatedUnions2.ts, 18, 17))
56+
57+
if (Math.random() > 0.5) {
58+
>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
59+
>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
60+
>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
61+
62+
return callback(...args);
63+
>callback : Symbol(callback, Decl(correlatedUnions2.ts, 16, 7))
64+
>args : Symbol(args, Decl(correlatedUnions2.ts, 18, 17))
65+
}
66+
};
67+
};
68+
69+
function wrapAll(callbacks: SomeCallbacks): SomeCallbacks {
70+
>wrapAll : Symbol(wrapAll, Decl(correlatedUnions2.ts, 23, 2))
71+
>callbacks : Symbol(callbacks, Decl(correlatedUnions2.ts, 25, 17))
72+
>SomeCallbacks : Symbol(SomeCallbacks, Decl(correlatedUnions2.ts, 5, 2))
73+
>SomeCallbacks : Symbol(SomeCallbacks, Decl(correlatedUnions2.ts, 5, 2))
74+
75+
const wrapped = {} as SomeCallbacks;
76+
>wrapped : Symbol(wrapped, Decl(correlatedUnions2.ts, 26, 7))
77+
>SomeCallbacks : Symbol(SomeCallbacks, Decl(correlatedUnions2.ts, 5, 2))
78+
79+
for (let key in callbacks) {
80+
>key : Symbol(key, Decl(correlatedUnions2.ts, 27, 10))
81+
>callbacks : Symbol(callbacks, Decl(correlatedUnions2.ts, 25, 17))
82+
83+
wrapCallback(callbacks, wrapped, key as keyof SomeCallbacks);
84+
>wrapCallback : Symbol(wrapCallback, Decl(correlatedUnions2.ts, 11, 5))
85+
>callbacks : Symbol(callbacks, Decl(correlatedUnions2.ts, 25, 17))
86+
>wrapped : Symbol(wrapped, Decl(correlatedUnions2.ts, 26, 7))
87+
>key : Symbol(key, Decl(correlatedUnions2.ts, 27, 10))
88+
>SomeCallbacks : Symbol(SomeCallbacks, Decl(correlatedUnions2.ts, 5, 2))
89+
}
90+
return wrapped;
91+
>wrapped : Symbol(wrapped, Decl(correlatedUnions2.ts, 26, 7))
92+
}
93+
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
//// [tests/cases/compiler/correlatedUnions2.ts] ////
2+
3+
=== correlatedUnions2.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/61676
5+
6+
type Definitions = {
7+
>Definitions : Definitions
8+
> : ^^^^^^^^^^^
9+
10+
onFoo: [arg: number];
11+
>onFoo : [arg: number]
12+
> : ^^^^^^^^^^^^^
13+
14+
onBar: [arg: string];
15+
>onBar : [arg: string]
16+
> : ^^^^^^^^^^^^^
17+
18+
};
19+
20+
type SomeCallbacks = {
21+
>SomeCallbacks : SomeCallbacks
22+
> : ^^^^^^^^^^^^^
23+
24+
[K in keyof Definitions]: (...args: Definitions[K]) => void;
25+
>args : Definitions[K]
26+
> : ^^^^^^^^^^^^^^
27+
28+
};
29+
30+
const wrapCallback = <K extends keyof SomeCallbacks>(
31+
>wrapCallback : <K extends keyof SomeCallbacks>(source: SomeCallbacks, target: SomeCallbacks, key: K) => void
32+
> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^^^^^^^
33+
><K extends keyof SomeCallbacks>( source: SomeCallbacks, target: SomeCallbacks, key: K,) => { const callback = source[key]; target[key] = (...args) => { if (Math.random() > 0.5) { return callback(...args); } };} : <K extends keyof SomeCallbacks>(source: SomeCallbacks, target: SomeCallbacks, key: K) => void
34+
> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^^^^^^^
35+
36+
source: SomeCallbacks,
37+
>source : SomeCallbacks
38+
> : ^^^^^^^^^^^^^
39+
40+
target: SomeCallbacks,
41+
>target : SomeCallbacks
42+
> : ^^^^^^^^^^^^^
43+
44+
key: K,
45+
>key : K
46+
> : ^
47+
48+
) => {
49+
const callback = source[key];
50+
>callback : SomeCallbacks[K]
51+
> : ^^^^^^^^^^^^^^^^
52+
>source[key] : SomeCallbacks[K]
53+
> : ^^^^^^^^^^^^^^^^
54+
>source : SomeCallbacks
55+
> : ^^^^^^^^^^^^^
56+
>key : K
57+
> : ^
58+
59+
target[key] = (...args) => {
60+
>target[key] = (...args) => { if (Math.random() > 0.5) { return callback(...args); } } : (...args: Definitions[K]) => void
61+
> : ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^
62+
>target[key] : SomeCallbacks[K]
63+
> : ^^^^^^^^^^^^^^^^
64+
>target : SomeCallbacks
65+
> : ^^^^^^^^^^^^^
66+
>key : K
67+
> : ^
68+
>(...args) => { if (Math.random() > 0.5) { return callback(...args); } } : (...args: Definitions[K]) => void
69+
> : ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^
70+
>args : Definitions[K]
71+
> : ^^^^^^^^^^^^^^
72+
73+
if (Math.random() > 0.5) {
74+
>Math.random() > 0.5 : boolean
75+
> : ^^^^^^^
76+
>Math.random() : number
77+
> : ^^^^^^
78+
>Math.random : () => number
79+
> : ^^^^^^
80+
>Math : Math
81+
> : ^^^^
82+
>random : () => number
83+
> : ^^^^^^
84+
>0.5 : 0.5
85+
> : ^^^
86+
87+
return callback(...args);
88+
>callback(...args) : void
89+
> : ^^^^
90+
>callback : SomeCallbacks[K]
91+
> : ^^^^^^^^^^^^^^^^
92+
>...args : string | number
93+
> : ^^^^^^^^^^^^^^^
94+
>args : Definitions[K]
95+
> : ^^^^^^^^^^^^^^
96+
}
97+
};
98+
};
99+
100+
function wrapAll(callbacks: SomeCallbacks): SomeCallbacks {
101+
>wrapAll : (callbacks: SomeCallbacks) => SomeCallbacks
102+
> : ^ ^^ ^^^^^
103+
>callbacks : SomeCallbacks
104+
> : ^^^^^^^^^^^^^
105+
106+
const wrapped = {} as SomeCallbacks;
107+
>wrapped : SomeCallbacks
108+
> : ^^^^^^^^^^^^^
109+
>{} as SomeCallbacks : SomeCallbacks
110+
> : ^^^^^^^^^^^^^
111+
>{} : {}
112+
> : ^^
113+
114+
for (let key in callbacks) {
115+
>key : string
116+
> : ^^^^^^
117+
>callbacks : SomeCallbacks
118+
> : ^^^^^^^^^^^^^
119+
120+
wrapCallback(callbacks, wrapped, key as keyof SomeCallbacks);
121+
>wrapCallback(callbacks, wrapped, key as keyof SomeCallbacks) : void
122+
> : ^^^^
123+
>wrapCallback : <K extends keyof SomeCallbacks>(source: SomeCallbacks, target: SomeCallbacks, key: K) => void
124+
> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^ ^^ ^^^^^^^^^
125+
>callbacks : SomeCallbacks
126+
> : ^^^^^^^^^^^^^
127+
>wrapped : SomeCallbacks
128+
> : ^^^^^^^^^^^^^
129+
>key as keyof SomeCallbacks : keyof Definitions
130+
> : ^^^^^^^^^^^^^^^^^
131+
>key : string
132+
> : ^^^^^^
133+
}
134+
return wrapped;
135+
>wrapped : SomeCallbacks
136+
> : ^^^^^^^^^^^^^
137+
}
138+
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
//// [tests/cases/compiler/correlatedUnions3.ts] ////
2+
3+
=== correlatedUnions3.ts ===
4+
type Definitions = {
5+
>Definitions : Symbol(Definitions, Decl(correlatedUnions3.ts, 0, 0))
6+
7+
onFoo: [arg: number];
8+
>onFoo : Symbol(onFoo, Decl(correlatedUnions3.ts, 0, 20))
9+
10+
onBar: [arg: string];
11+
>onBar : Symbol(onBar, Decl(correlatedUnions3.ts, 1, 23))
12+
13+
};
14+
15+
type SomeCallbacks = {
16+
>SomeCallbacks : Symbol(SomeCallbacks, Decl(correlatedUnions3.ts, 3, 2))
17+
18+
[K in keyof Definitions]?: (...args: Definitions[K]) => void;
19+
>K : Symbol(K, Decl(correlatedUnions3.ts, 6, 3))
20+
>Definitions : Symbol(Definitions, Decl(correlatedUnions3.ts, 0, 0))
21+
>args : Symbol(args, Decl(correlatedUnions3.ts, 6, 30))
22+
>Definitions : Symbol(Definitions, Decl(correlatedUnions3.ts, 0, 0))
23+
>K : Symbol(K, Decl(correlatedUnions3.ts, 6, 3))
24+
25+
};
26+
27+
const wrapCallback = <K extends keyof SomeCallbacks>(
28+
>wrapCallback : Symbol(wrapCallback, Decl(correlatedUnions3.ts, 9, 5))
29+
>K : Symbol(K, Decl(correlatedUnions3.ts, 9, 22))
30+
>SomeCallbacks : Symbol(SomeCallbacks, Decl(correlatedUnions3.ts, 3, 2))
31+
32+
source: SomeCallbacks,
33+
>source : Symbol(source, Decl(correlatedUnions3.ts, 9, 53))
34+
>SomeCallbacks : Symbol(SomeCallbacks, Decl(correlatedUnions3.ts, 3, 2))
35+
36+
target: SomeCallbacks,
37+
>target : Symbol(target, Decl(correlatedUnions3.ts, 10, 24))
38+
>SomeCallbacks : Symbol(SomeCallbacks, Decl(correlatedUnions3.ts, 3, 2))
39+
40+
key: K,
41+
>key : Symbol(key, Decl(correlatedUnions3.ts, 11, 24))
42+
>K : Symbol(K, Decl(correlatedUnions3.ts, 9, 22))
43+
44+
) => {
45+
const callback = source[key];
46+
>callback : Symbol(callback, Decl(correlatedUnions3.ts, 14, 7))
47+
>source : Symbol(source, Decl(correlatedUnions3.ts, 9, 53))
48+
>key : Symbol(key, Decl(correlatedUnions3.ts, 11, 24))
49+
50+
target[key] =
51+
>target : Symbol(target, Decl(correlatedUnions3.ts, 10, 24))
52+
>key : Symbol(key, Decl(correlatedUnions3.ts, 11, 24))
53+
54+
callback &&
55+
>callback : Symbol(callback, Decl(correlatedUnions3.ts, 14, 7))
56+
57+
((...args) => {
58+
>args : Symbol(args, Decl(correlatedUnions3.ts, 17, 6))
59+
60+
if (Math.random() > 0.5) {
61+
>Math.random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
62+
>Math : Symbol(Math, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
63+
>random : Symbol(Math.random, Decl(lib.es5.d.ts, --, --))
64+
65+
return callback(...args);
66+
>callback : Symbol(callback, Decl(correlatedUnions3.ts, 14, 7))
67+
>args : Symbol(args, Decl(correlatedUnions3.ts, 17, 6))
68+
}
69+
});
70+
};
71+
72+
function wrapAll(callbacks: SomeCallbacks): SomeCallbacks {
73+
>wrapAll : Symbol(wrapAll, Decl(correlatedUnions3.ts, 22, 2))
74+
>callbacks : Symbol(callbacks, Decl(correlatedUnions3.ts, 24, 17))
75+
>SomeCallbacks : Symbol(SomeCallbacks, Decl(correlatedUnions3.ts, 3, 2))
76+
>SomeCallbacks : Symbol(SomeCallbacks, Decl(correlatedUnions3.ts, 3, 2))
77+
78+
const wrapped: SomeCallbacks = {};
79+
>wrapped : Symbol(wrapped, Decl(correlatedUnions3.ts, 25, 7))
80+
>SomeCallbacks : Symbol(SomeCallbacks, Decl(correlatedUnions3.ts, 3, 2))
81+
82+
for (let key in callbacks) {
83+
>key : Symbol(key, Decl(correlatedUnions3.ts, 26, 10))
84+
>callbacks : Symbol(callbacks, Decl(correlatedUnions3.ts, 24, 17))
85+
86+
wrapCallback(callbacks, wrapped, key as keyof SomeCallbacks);
87+
>wrapCallback : Symbol(wrapCallback, Decl(correlatedUnions3.ts, 9, 5))
88+
>callbacks : Symbol(callbacks, Decl(correlatedUnions3.ts, 24, 17))
89+
>wrapped : Symbol(wrapped, Decl(correlatedUnions3.ts, 25, 7))
90+
>key : Symbol(key, Decl(correlatedUnions3.ts, 26, 10))
91+
>SomeCallbacks : Symbol(SomeCallbacks, Decl(correlatedUnions3.ts, 3, 2))
92+
}
93+
return wrapped;
94+
>wrapped : Symbol(wrapped, Decl(correlatedUnions3.ts, 25, 7))
95+
}
96+

0 commit comments

Comments
 (0)