Skip to content

Commit be33c06

Browse files
committed
Do not resolve apparent type of mapped types with a tuple constraint
1 parent 6b43f82 commit be33c06

4 files changed

+173
-1
lines changed

src/compiler/checker.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -13675,7 +13675,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1367513675
const typeVariable = getHomomorphicTypeVariable(type);
1367613676
if (typeVariable && !type.declaration.nameType) {
1367713677
const constraint = getConstraintOfTypeParameter(typeVariable);
13678-
if (constraint && isArrayOrTupleType(constraint)) {
13678+
if (constraint && isArrayType(constraint)) {
1367913679
return instantiateType(type, prependTypeMapping(typeVariable, constraint, type.mapper));
1368013680
}
1368113681
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
=== tests/cases/compiler/reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts ===
2+
type Tuple<T> = readonly [T, ...T[]];
3+
>Tuple : Symbol(Tuple, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 0, 0))
4+
>T : Symbol(T, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 0, 11))
5+
>T : Symbol(T, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 0, 11))
6+
>T : Symbol(T, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 0, 11))
7+
8+
declare function bindAll<
9+
>bindAll : Symbol(bindAll, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 0, 37))
10+
11+
TTarget extends EventTarget,
12+
>TTarget : Symbol(TTarget, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 2, 25))
13+
>EventTarget : Symbol(EventTarget, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
14+
15+
TTypes extends Tuple<keyof TTarget & `on${any}`>
16+
>TTypes : Symbol(TTypes, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 3, 30))
17+
>Tuple : Symbol(Tuple, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 0, 0))
18+
>TTarget : Symbol(TTarget, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 2, 25))
19+
20+
>(
21+
target: TTarget,
22+
>target : Symbol(target, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 5, 2))
23+
>TTarget : Symbol(TTarget, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 2, 25))
24+
25+
bindings: {
26+
>bindings : Symbol(bindings, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 6, 18))
27+
28+
[K in keyof TTypes]: {
29+
>K : Symbol(K, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 8, 5))
30+
>TTypes : Symbol(TTypes, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 3, 30))
31+
32+
type: TTypes[K];
33+
>type : Symbol(type, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 8, 26))
34+
>TTypes : Symbol(TTypes, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 3, 30))
35+
>K : Symbol(K, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 8, 5))
36+
37+
listener: (
38+
>listener : Symbol(listener, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 9, 22))
39+
40+
ev: Parameters<Extract<TTarget[TTypes[K]], (...args: any[]) => any>>[0]
41+
>ev : Symbol(ev, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 10, 17))
42+
>Parameters : Symbol(Parameters, Decl(lib.es5.d.ts, --, --))
43+
>Extract : Symbol(Extract, Decl(lib.es5.d.ts, --, --))
44+
>TTarget : Symbol(TTarget, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 2, 25))
45+
>TTypes : Symbol(TTypes, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 3, 30))
46+
>K : Symbol(K, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 8, 5))
47+
>args : Symbol(args, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 11, 52))
48+
49+
) => void;
50+
};
51+
}
52+
): void;
53+
54+
bindAll({} as HTMLButtonElement, [
55+
>bindAll : Symbol(bindAll, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 0, 37))
56+
>HTMLButtonElement : Symbol(HTMLButtonElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
57+
{
58+
type: "onclick",
59+
>type : Symbol(type, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 18, 3))
60+
61+
listener: (event) => {},
62+
>listener : Symbol(listener, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 19, 20))
63+
>event : Symbol(event, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 20, 15))
64+
65+
},
66+
{
67+
type: "onkeydown",
68+
>type : Symbol(type, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 22, 3))
69+
70+
listener: (event) => {},
71+
>listener : Symbol(listener, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 23, 22))
72+
>event : Symbol(event, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 24, 15))
73+
74+
},
75+
]);
76+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
=== tests/cases/compiler/reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts ===
2+
type Tuple<T> = readonly [T, ...T[]];
3+
>Tuple : Tuple<T>
4+
5+
declare function bindAll<
6+
>bindAll : <TTarget extends EventTarget, TTypes extends Tuple<keyof TTarget & `on${any}`>>(target: TTarget, bindings: { [K in keyof TTypes]: { type: TTypes[K]; listener: (ev: Parameters<Extract<TTarget[TTypes[K]], (...args: any[]) => any>>[0]) => void; }; }) => void
7+
8+
TTarget extends EventTarget,
9+
TTypes extends Tuple<keyof TTarget & `on${any}`>
10+
>(
11+
target: TTarget,
12+
>target : TTarget
13+
14+
bindings: {
15+
>bindings : { [K in keyof TTypes]: { type: TTypes[K]; listener: (ev: Parameters<Extract<TTarget[TTypes[K]], (...args: any[]) => any>>[0]) => void; }; }
16+
17+
[K in keyof TTypes]: {
18+
type: TTypes[K];
19+
>type : TTypes[K]
20+
21+
listener: (
22+
>listener : (ev: Parameters<Extract<TTarget[TTypes[K]], (...args: any[]) => any>>[0]) => void
23+
24+
ev: Parameters<Extract<TTarget[TTypes[K]], (...args: any[]) => any>>[0]
25+
>ev : Parameters<Extract<TTarget[TTypes[K]], (...args: any[]) => any>>[0]
26+
>args : any[]
27+
28+
) => void;
29+
};
30+
}
31+
): void;
32+
33+
bindAll({} as HTMLButtonElement, [
34+
>bindAll({} as HTMLButtonElement, [ { type: "onclick", listener: (event) => {}, }, { type: "onkeydown", listener: (event) => {}, },]) : void
35+
>bindAll : <TTarget extends EventTarget, TTypes extends Tuple<keyof TTarget & `on${any}`>>(target: TTarget, bindings: { [K in keyof TTypes]: { type: TTypes[K]; listener: (ev: Parameters<Extract<TTarget[TTypes[K]], (...args: any[]) => any>>[0]) => void; }; }) => void
36+
>{} as HTMLButtonElement : HTMLButtonElement
37+
>{} : {}
38+
>[ { type: "onclick", listener: (event) => {}, }, { type: "onkeydown", listener: (event) => {}, },] : [{ type: "onclick"; listener: (event: MouseEvent) => void; }, { type: "onkeydown"; listener: (event: KeyboardEvent) => void; }]
39+
{
40+
>{ type: "onclick", listener: (event) => {}, } : { type: "onclick"; listener: (event: MouseEvent) => void; }
41+
42+
type: "onclick",
43+
>type : "onclick"
44+
>"onclick" : "onclick"
45+
46+
listener: (event) => {},
47+
>listener : (event: MouseEvent) => void
48+
>(event) => {} : (event: MouseEvent) => void
49+
>event : MouseEvent
50+
51+
},
52+
{
53+
>{ type: "onkeydown", listener: (event) => {}, } : { type: "onkeydown"; listener: (event: KeyboardEvent) => void; }
54+
55+
type: "onkeydown",
56+
>type : "onkeydown"
57+
>"onkeydown" : "onkeydown"
58+
59+
listener: (event) => {},
60+
>listener : (event: KeyboardEvent) => void
61+
>(event) => {} : (event: KeyboardEvent) => void
62+
>event : KeyboardEvent
63+
64+
},
65+
]);
66+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// @strict: true
2+
// @noEmit: true
3+
4+
type Tuple<T> = readonly [T, ...T[]];
5+
6+
declare function bindAll<
7+
TTarget extends EventTarget,
8+
TTypes extends Tuple<keyof TTarget & `on${any}`>
9+
>(
10+
target: TTarget,
11+
bindings: {
12+
[K in keyof TTypes]: {
13+
type: TTypes[K];
14+
listener: (
15+
ev: Parameters<Extract<TTarget[TTypes[K]], (...args: any[]) => any>>[0]
16+
) => void;
17+
};
18+
}
19+
): void;
20+
21+
bindAll({} as HTMLButtonElement, [
22+
{
23+
type: "onclick",
24+
listener: (event) => {},
25+
},
26+
{
27+
type: "onkeydown",
28+
listener: (event) => {},
29+
},
30+
]);

0 commit comments

Comments
 (0)