Do not resolve apparent type of mapped types with a tuple constraint (#52651)

This commit is contained in:
Mateusz Burzyński
2023-03-15 10:46:12 -07:00
committed by GitHub
parent eb6aaea86e
commit 074bf34633
4 changed files with 173 additions and 1 deletions
+1 -1
View File
@@ -13859,7 +13859,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const typeVariable = getHomomorphicTypeVariable(type);
if (typeVariable && !type.declaration.nameType) {
const constraint = getConstraintOfTypeParameter(typeVariable);
if (constraint && isArrayOrTupleType(constraint)) {
if (constraint && isArrayType(constraint)) {
return instantiateType(type, prependTypeMapping(typeVariable, constraint, type.mapper));
}
}
@@ -0,0 +1,76 @@
=== tests/cases/compiler/reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts ===
type Tuple<T> = readonly [T, ...T[]];
>Tuple : Symbol(Tuple, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 0, 0))
>T : Symbol(T, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 0, 11))
>T : Symbol(T, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 0, 11))
>T : Symbol(T, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 0, 11))
declare function bindAll<
>bindAll : Symbol(bindAll, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 0, 37))
TTarget extends EventTarget,
>TTarget : Symbol(TTarget, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 2, 25))
>EventTarget : Symbol(EventTarget, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
TTypes extends Tuple<keyof TTarget & `on${any}`>
>TTypes : Symbol(TTypes, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 3, 30))
>Tuple : Symbol(Tuple, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 0, 0))
>TTarget : Symbol(TTarget, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 2, 25))
>(
target: TTarget,
>target : Symbol(target, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 5, 2))
>TTarget : Symbol(TTarget, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 2, 25))
bindings: {
>bindings : Symbol(bindings, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 6, 18))
[K in keyof TTypes]: {
>K : Symbol(K, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 8, 5))
>TTypes : Symbol(TTypes, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 3, 30))
type: TTypes[K];
>type : Symbol(type, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 8, 26))
>TTypes : Symbol(TTypes, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 3, 30))
>K : Symbol(K, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 8, 5))
listener: (
>listener : Symbol(listener, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 9, 22))
ev: Parameters<Extract<TTarget[TTypes[K]], (...args: any[]) => any>>[0]
>ev : Symbol(ev, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 10, 17))
>Parameters : Symbol(Parameters, Decl(lib.es5.d.ts, --, --))
>Extract : Symbol(Extract, Decl(lib.es5.d.ts, --, --))
>TTarget : Symbol(TTarget, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 2, 25))
>TTypes : Symbol(TTypes, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 3, 30))
>K : Symbol(K, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 8, 5))
>args : Symbol(args, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 11, 52))
) => void;
};
}
): void;
bindAll({} as HTMLButtonElement, [
>bindAll : Symbol(bindAll, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 0, 37))
>HTMLButtonElement : Symbol(HTMLButtonElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
{
type: "onclick",
>type : Symbol(type, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 18, 3))
listener: (event) => {},
>listener : Symbol(listener, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 19, 20))
>event : Symbol(event, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 20, 15))
},
{
type: "onkeydown",
>type : Symbol(type, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 22, 3))
listener: (event) => {},
>listener : Symbol(listener, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 23, 22))
>event : Symbol(event, Decl(reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts, 24, 15))
},
]);
@@ -0,0 +1,66 @@
=== tests/cases/compiler/reverseMappedTypeContextualTypesPerElementOfTupleConstraint.ts ===
type Tuple<T> = readonly [T, ...T[]];
>Tuple : Tuple<T>
declare function bindAll<
>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
TTarget extends EventTarget,
TTypes extends Tuple<keyof TTarget & `on${any}`>
>(
target: TTarget,
>target : TTarget
bindings: {
>bindings : { [K in keyof TTypes]: { type: TTypes[K]; listener: (ev: Parameters<Extract<TTarget[TTypes[K]], (...args: any[]) => any>>[0]) => void; }; }
[K in keyof TTypes]: {
type: TTypes[K];
>type : TTypes[K]
listener: (
>listener : (ev: Parameters<Extract<TTarget[TTypes[K]], (...args: any[]) => any>>[0]) => void
ev: Parameters<Extract<TTarget[TTypes[K]], (...args: any[]) => any>>[0]
>ev : Parameters<Extract<TTarget[TTypes[K]], (...args: any[]) => any>>[0]
>args : any[]
) => void;
};
}
): void;
bindAll({} as HTMLButtonElement, [
>bindAll({} as HTMLButtonElement, [ { type: "onclick", listener: (event) => {}, }, { type: "onkeydown", listener: (event) => {}, },]) : void
>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
>{} as HTMLButtonElement : HTMLButtonElement
>{} : {}
>[ { type: "onclick", listener: (event) => {}, }, { type: "onkeydown", listener: (event) => {}, },] : [{ type: "onclick"; listener: (event: MouseEvent) => void; }, { type: "onkeydown"; listener: (event: KeyboardEvent) => void; }]
{
>{ type: "onclick", listener: (event) => {}, } : { type: "onclick"; listener: (event: MouseEvent) => void; }
type: "onclick",
>type : "onclick"
>"onclick" : "onclick"
listener: (event) => {},
>listener : (event: MouseEvent) => void
>(event) => {} : (event: MouseEvent) => void
>event : MouseEvent
},
{
>{ type: "onkeydown", listener: (event) => {}, } : { type: "onkeydown"; listener: (event: KeyboardEvent) => void; }
type: "onkeydown",
>type : "onkeydown"
>"onkeydown" : "onkeydown"
listener: (event) => {},
>listener : (event: KeyboardEvent) => void
>(event) => {} : (event: KeyboardEvent) => void
>event : KeyboardEvent
},
]);
@@ -0,0 +1,30 @@
// @strict: true
// @noEmit: true
type Tuple<T> = readonly [T, ...T[]];
declare function 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;
bindAll({} as HTMLButtonElement, [
{
type: "onclick",
listener: (event) => {},
},
{
type: "onkeydown",
listener: (event) => {},
},
]);