Fixed single signature type parameter leak (#58008)

Co-authored-by: Wesley Wigham <wewigham@microsoft.com>
This commit is contained in:
Mateusz Burzyński 2024-04-19 18:15:42 +01:00 committed by GitHub
parent 10b784aa88
commit e0755dc7c1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 140 additions and 1 deletions

View File

@ -19545,13 +19545,18 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const typeArguments = map(typeParameters, t => getMappedType(t, combinedMapper));
const newAliasSymbol = aliasSymbol || type.aliasSymbol;
const newAliasTypeArguments = aliasSymbol ? aliasTypeArguments : instantiateTypes(type.aliasTypeArguments, mapper);
const id = getTypeListId(typeArguments) + getAliasId(newAliasSymbol, newAliasTypeArguments);
const id = (type.objectFlags & ObjectFlags.SingleSignatureType ? "S" : "") + getTypeListId(typeArguments) + getAliasId(newAliasSymbol, newAliasTypeArguments);
if (!target.instantiations) {
target.instantiations = new Map<string, Type>();
target.instantiations.set(getTypeListId(typeParameters) + getAliasId(target.aliasSymbol, target.aliasTypeArguments), target);
}
let result = target.instantiations.get(id);
if (!result) {
if (type.objectFlags & ObjectFlags.SingleSignatureType) {
result = instantiateAnonymousType(type, mapper);
target.instantiations.set(id, result);
return result;
}
const newMapper = createTypeMapper(typeParameters, typeArguments);
result = target.objectFlags & ObjectFlags.Reference ? createDeferredTypeReference((type as DeferredTypeReference).target, (type as DeferredTypeReference).node, newMapper, newAliasSymbol, newAliasTypeArguments) :
target.objectFlags & ObjectFlags.Mapped ? instantiateMappedType(target as MappedType, newMapper, newAliasSymbol, newAliasTypeArguments) :

View File

@ -0,0 +1,44 @@
//// [tests/cases/compiler/genericCallInferenceWithGenericLocalFunction.ts] ////
=== genericCallInferenceWithGenericLocalFunction.ts ===
// https://github.com/microsoft/TypeScript/issues/43961
const createTransform = <I, O>(tr: (from: I) => O) => tr;
>createTransform : Symbol(createTransform, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 5))
>I : Symbol(I, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 25))
>O : Symbol(O, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 27))
>tr : Symbol(tr, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 31))
>from : Symbol(from, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 36))
>I : Symbol(I, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 25))
>O : Symbol(O, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 27))
>tr : Symbol(tr, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 31))
function withP2<P>(p: P) {
>withP2 : Symbol(withP2, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 57))
>P : Symbol(P, Decl(genericCallInferenceWithGenericLocalFunction.ts, 4, 16))
>p : Symbol(p, Decl(genericCallInferenceWithGenericLocalFunction.ts, 4, 19))
>P : Symbol(P, Decl(genericCallInferenceWithGenericLocalFunction.ts, 4, 16))
const m = <I,>(from: I) => ({ ...from, ...p });
>m : Symbol(m, Decl(genericCallInferenceWithGenericLocalFunction.ts, 5, 7))
>I : Symbol(I, Decl(genericCallInferenceWithGenericLocalFunction.ts, 5, 13))
>from : Symbol(from, Decl(genericCallInferenceWithGenericLocalFunction.ts, 5, 17))
>I : Symbol(I, Decl(genericCallInferenceWithGenericLocalFunction.ts, 5, 13))
>from : Symbol(from, Decl(genericCallInferenceWithGenericLocalFunction.ts, 5, 17))
>p : Symbol(p, Decl(genericCallInferenceWithGenericLocalFunction.ts, 4, 19))
return createTransform(m);
>createTransform : Symbol(createTransform, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 5))
>m : Symbol(m, Decl(genericCallInferenceWithGenericLocalFunction.ts, 5, 7))
}
const addP2 = withP2({ foo: 1 });
>addP2 : Symbol(addP2, Decl(genericCallInferenceWithGenericLocalFunction.ts, 9, 5))
>withP2 : Symbol(withP2, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 57))
>foo : Symbol(foo, Decl(genericCallInferenceWithGenericLocalFunction.ts, 9, 22))
const added2 = addP2({ bar: 2 });
>added2 : Symbol(added2, Decl(genericCallInferenceWithGenericLocalFunction.ts, 10, 5))
>addP2 : Symbol(addP2, Decl(genericCallInferenceWithGenericLocalFunction.ts, 9, 5))
>bar : Symbol(bar, Decl(genericCallInferenceWithGenericLocalFunction.ts, 10, 22))

View File

@ -0,0 +1,76 @@
//// [tests/cases/compiler/genericCallInferenceWithGenericLocalFunction.ts] ////
=== genericCallInferenceWithGenericLocalFunction.ts ===
// https://github.com/microsoft/TypeScript/issues/43961
const createTransform = <I, O>(tr: (from: I) => O) => tr;
>createTransform : <I, O>(tr: (from: I) => O) => (from: I) => O
> : ^ ^^ ^^ ^^ ^^^^^^ ^^ ^^^^^
><I, O>(tr: (from: I) => O) => tr : <I, O>(tr: (from: I) => O) => (from: I) => O
> : ^ ^^ ^^ ^^ ^^^^^^ ^^ ^^^^^
>tr : (from: I) => O
> : ^ ^^ ^^^^^
>from : I
> : ^
>tr : (from: I) => O
> : ^ ^^ ^^^^^
function withP2<P>(p: P) {
>withP2 : <P>(p: P) => <I>(from: I) => I & P
> : ^ ^^ ^^ ^^^^^^^^^ ^^^^^^^^^^^^^
>p : P
> : ^
const m = <I,>(from: I) => ({ ...from, ...p });
>m : <I>(from: I) => I & P
> : ^ ^^ ^^ ^^^^^^^^^^
><I,>(from: I) => ({ ...from, ...p }) : <I>(from: I) => I & P
> : ^ ^^ ^^ ^^^^^^^^^^
>from : I
> : ^
>({ ...from, ...p }) : I & P
> : ^^^^^
>{ ...from, ...p } : I & P
> : ^^^^^
>from : I
> : ^
>p : P
> : ^
return createTransform(m);
>createTransform(m) : <I>(from: I) => I & P
> : ^^^^ ^^^^^^^^^^^^^
>createTransform : <I, O>(tr: (from: I) => O) => (from: I) => O
> : ^ ^^ ^^ ^^ ^^^^^^ ^^ ^^^^^^
>m : <I>(from: I) => I & P
> : ^ ^^ ^^ ^^^^^^^^^^
}
const addP2 = withP2({ foo: 1 });
>addP2 : <I>(from: I) => I & { foo: number; }
> : ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>withP2({ foo: 1 }) : <I>(from: I) => I & { foo: number; }
> : ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>withP2 : <P>(p: P) => <I>(from: I) => I & P
> : ^ ^^ ^^ ^^^^^^^^^ ^^^^^^^^^^^^^
>{ foo: 1 } : { foo: number; }
> : ^^^^^^^^^^^^^^^^
>foo : number
> : ^^^^^^
>1 : 1
> : ^
const added2 = addP2({ bar: 2 });
>added2 : { bar: number; } & { foo: number; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>addP2({ bar: 2 }) : { bar: number; } & { foo: number; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>addP2 : <I>(from: I) => I & { foo: number; }
> : ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>{ bar: 2 } : { bar: number; }
> : ^^^^^^^^^^^^^^^^
>bar : number
> : ^^^^^^
>2 : 2
> : ^

View File

@ -0,0 +1,14 @@
// @strict: true
// @noEmit: true
// https://github.com/microsoft/TypeScript/issues/43961
const createTransform = <I, O>(tr: (from: I) => O) => tr;
function withP2<P>(p: P) {
const m = <I,>(from: I) => ({ ...from, ...p });
return createTransform(m);
}
const addP2 = withP2({ foo: 1 });
const added2 = addP2({ bar: 2 });