Skip to content

Commit e0755dc

Browse files
Andaristweswigham
andauthored
Fixed single signature type parameter leak (#58008)
Co-authored-by: Wesley Wigham <[email protected]>
1 parent 10b784a commit e0755dc

File tree

4 files changed

+140
-1
lines changed

4 files changed

+140
-1
lines changed

src/compiler/checker.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -19545,13 +19545,18 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1954519545
const typeArguments = map(typeParameters, t => getMappedType(t, combinedMapper));
1954619546
const newAliasSymbol = aliasSymbol || type.aliasSymbol;
1954719547
const newAliasTypeArguments = aliasSymbol ? aliasTypeArguments : instantiateTypes(type.aliasTypeArguments, mapper);
19548-
const id = getTypeListId(typeArguments) + getAliasId(newAliasSymbol, newAliasTypeArguments);
19548+
const id = (type.objectFlags & ObjectFlags.SingleSignatureType ? "S" : "") + getTypeListId(typeArguments) + getAliasId(newAliasSymbol, newAliasTypeArguments);
1954919549
if (!target.instantiations) {
1955019550
target.instantiations = new Map<string, Type>();
1955119551
target.instantiations.set(getTypeListId(typeParameters) + getAliasId(target.aliasSymbol, target.aliasTypeArguments), target);
1955219552
}
1955319553
let result = target.instantiations.get(id);
1955419554
if (!result) {
19555+
if (type.objectFlags & ObjectFlags.SingleSignatureType) {
19556+
result = instantiateAnonymousType(type, mapper);
19557+
target.instantiations.set(id, result);
19558+
return result;
19559+
}
1955519560
const newMapper = createTypeMapper(typeParameters, typeArguments);
1955619561
result = target.objectFlags & ObjectFlags.Reference ? createDeferredTypeReference((type as DeferredTypeReference).target, (type as DeferredTypeReference).node, newMapper, newAliasSymbol, newAliasTypeArguments) :
1955719562
target.objectFlags & ObjectFlags.Mapped ? instantiateMappedType(target as MappedType, newMapper, newAliasSymbol, newAliasTypeArguments) :
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//// [tests/cases/compiler/genericCallInferenceWithGenericLocalFunction.ts] ////
2+
3+
=== genericCallInferenceWithGenericLocalFunction.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/43961
5+
6+
const createTransform = <I, O>(tr: (from: I) => O) => tr;
7+
>createTransform : Symbol(createTransform, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 5))
8+
>I : Symbol(I, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 25))
9+
>O : Symbol(O, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 27))
10+
>tr : Symbol(tr, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 31))
11+
>from : Symbol(from, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 36))
12+
>I : Symbol(I, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 25))
13+
>O : Symbol(O, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 27))
14+
>tr : Symbol(tr, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 31))
15+
16+
function withP2<P>(p: P) {
17+
>withP2 : Symbol(withP2, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 57))
18+
>P : Symbol(P, Decl(genericCallInferenceWithGenericLocalFunction.ts, 4, 16))
19+
>p : Symbol(p, Decl(genericCallInferenceWithGenericLocalFunction.ts, 4, 19))
20+
>P : Symbol(P, Decl(genericCallInferenceWithGenericLocalFunction.ts, 4, 16))
21+
22+
const m = <I,>(from: I) => ({ ...from, ...p });
23+
>m : Symbol(m, Decl(genericCallInferenceWithGenericLocalFunction.ts, 5, 7))
24+
>I : Symbol(I, Decl(genericCallInferenceWithGenericLocalFunction.ts, 5, 13))
25+
>from : Symbol(from, Decl(genericCallInferenceWithGenericLocalFunction.ts, 5, 17))
26+
>I : Symbol(I, Decl(genericCallInferenceWithGenericLocalFunction.ts, 5, 13))
27+
>from : Symbol(from, Decl(genericCallInferenceWithGenericLocalFunction.ts, 5, 17))
28+
>p : Symbol(p, Decl(genericCallInferenceWithGenericLocalFunction.ts, 4, 19))
29+
30+
return createTransform(m);
31+
>createTransform : Symbol(createTransform, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 5))
32+
>m : Symbol(m, Decl(genericCallInferenceWithGenericLocalFunction.ts, 5, 7))
33+
}
34+
35+
const addP2 = withP2({ foo: 1 });
36+
>addP2 : Symbol(addP2, Decl(genericCallInferenceWithGenericLocalFunction.ts, 9, 5))
37+
>withP2 : Symbol(withP2, Decl(genericCallInferenceWithGenericLocalFunction.ts, 2, 57))
38+
>foo : Symbol(foo, Decl(genericCallInferenceWithGenericLocalFunction.ts, 9, 22))
39+
40+
const added2 = addP2({ bar: 2 });
41+
>added2 : Symbol(added2, Decl(genericCallInferenceWithGenericLocalFunction.ts, 10, 5))
42+
>addP2 : Symbol(addP2, Decl(genericCallInferenceWithGenericLocalFunction.ts, 9, 5))
43+
>bar : Symbol(bar, Decl(genericCallInferenceWithGenericLocalFunction.ts, 10, 22))
44+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
//// [tests/cases/compiler/genericCallInferenceWithGenericLocalFunction.ts] ////
2+
3+
=== genericCallInferenceWithGenericLocalFunction.ts ===
4+
// https://github.com/microsoft/TypeScript/issues/43961
5+
6+
const createTransform = <I, O>(tr: (from: I) => O) => tr;
7+
>createTransform : <I, O>(tr: (from: I) => O) => (from: I) => O
8+
> : ^ ^^ ^^ ^^ ^^^^^^ ^^ ^^^^^
9+
><I, O>(tr: (from: I) => O) => tr : <I, O>(tr: (from: I) => O) => (from: I) => O
10+
> : ^ ^^ ^^ ^^ ^^^^^^ ^^ ^^^^^
11+
>tr : (from: I) => O
12+
> : ^ ^^ ^^^^^
13+
>from : I
14+
> : ^
15+
>tr : (from: I) => O
16+
> : ^ ^^ ^^^^^
17+
18+
function withP2<P>(p: P) {
19+
>withP2 : <P>(p: P) => <I>(from: I) => I & P
20+
> : ^ ^^ ^^ ^^^^^^^^^ ^^^^^^^^^^^^^
21+
>p : P
22+
> : ^
23+
24+
const m = <I,>(from: I) => ({ ...from, ...p });
25+
>m : <I>(from: I) => I & P
26+
> : ^ ^^ ^^ ^^^^^^^^^^
27+
><I,>(from: I) => ({ ...from, ...p }) : <I>(from: I) => I & P
28+
> : ^ ^^ ^^ ^^^^^^^^^^
29+
>from : I
30+
> : ^
31+
>({ ...from, ...p }) : I & P
32+
> : ^^^^^
33+
>{ ...from, ...p } : I & P
34+
> : ^^^^^
35+
>from : I
36+
> : ^
37+
>p : P
38+
> : ^
39+
40+
return createTransform(m);
41+
>createTransform(m) : <I>(from: I) => I & P
42+
> : ^^^^ ^^^^^^^^^^^^^
43+
>createTransform : <I, O>(tr: (from: I) => O) => (from: I) => O
44+
> : ^ ^^ ^^ ^^ ^^^^^^ ^^ ^^^^^^
45+
>m : <I>(from: I) => I & P
46+
> : ^ ^^ ^^ ^^^^^^^^^^
47+
}
48+
49+
const addP2 = withP2({ foo: 1 });
50+
>addP2 : <I>(from: I) => I & { foo: number; }
51+
> : ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
52+
>withP2({ foo: 1 }) : <I>(from: I) => I & { foo: number; }
53+
> : ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
54+
>withP2 : <P>(p: P) => <I>(from: I) => I & P
55+
> : ^ ^^ ^^ ^^^^^^^^^ ^^^^^^^^^^^^^
56+
>{ foo: 1 } : { foo: number; }
57+
> : ^^^^^^^^^^^^^^^^
58+
>foo : number
59+
> : ^^^^^^
60+
>1 : 1
61+
> : ^
62+
63+
const added2 = addP2({ bar: 2 });
64+
>added2 : { bar: number; } & { foo: number; }
65+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
66+
>addP2({ bar: 2 }) : { bar: number; } & { foo: number; }
67+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
68+
>addP2 : <I>(from: I) => I & { foo: number; }
69+
> : ^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
70+
>{ bar: 2 } : { bar: number; }
71+
> : ^^^^^^^^^^^^^^^^
72+
>bar : number
73+
> : ^^^^^^
74+
>2 : 2
75+
> : ^
76+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// @strict: true
2+
// @noEmit: true
3+
4+
// https://github.com/microsoft/TypeScript/issues/43961
5+
6+
const createTransform = <I, O>(tr: (from: I) => O) => tr;
7+
8+
function withP2<P>(p: P) {
9+
const m = <I,>(from: I) => ({ ...from, ...p });
10+
return createTransform(m);
11+
}
12+
13+
const addP2 = withP2({ foo: 1 });
14+
const added2 = addP2({ bar: 2 });

0 commit comments

Comments
 (0)