mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 08:11:30 -06:00
Fix type parameter leak (#35949)
* Fix cloneSignature to include unionSignatures property * Add regression test
This commit is contained in:
parent
024b8c1e5f
commit
a8944e6844
@ -8774,6 +8774,7 @@ namespace ts {
|
||||
sig.minArgumentCount = minArgumentCount;
|
||||
sig.target = undefined;
|
||||
sig.mapper = undefined;
|
||||
sig.unionSignatures = undefined;
|
||||
return sig;
|
||||
}
|
||||
|
||||
@ -8782,6 +8783,7 @@ namespace ts {
|
||||
/*resolvedTypePredicate*/ undefined, sig.minArgumentCount, sig.flags & SignatureFlags.PropagatingFlags);
|
||||
result.target = sig.target;
|
||||
result.mapper = sig.mapper;
|
||||
result.unionSignatures = sig.unionSignatures;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
29
tests/baselines/reference/typeParameterLeak.js
Normal file
29
tests/baselines/reference/typeParameterLeak.js
Normal file
@ -0,0 +1,29 @@
|
||||
//// [typeParameterLeak.ts]
|
||||
// Repro from #35655
|
||||
|
||||
interface Box<T> { data: T }
|
||||
type BoxTypes = Box<{ x: string }> | Box<{ y: string }>;
|
||||
|
||||
type BoxFactoryFactory<TBox> = TBox extends Box<infer T> ? {
|
||||
(arg: T): BoxFactory<TBox> | undefined
|
||||
} : never;
|
||||
|
||||
interface BoxFactory<A> {
|
||||
getBox(): A,
|
||||
}
|
||||
|
||||
declare const f: BoxFactoryFactory<BoxTypes>;
|
||||
const b = f({ x: "", y: "" })?.getBox();
|
||||
if (b) {
|
||||
const x = b.data;
|
||||
}
|
||||
|
||||
|
||||
//// [typeParameterLeak.js]
|
||||
"use strict";
|
||||
// Repro from #35655
|
||||
var _a;
|
||||
var b = (_a = f({ x: "", y: "" })) === null || _a === void 0 ? void 0 : _a.getBox();
|
||||
if (b) {
|
||||
var x = b.data;
|
||||
}
|
||||
63
tests/baselines/reference/typeParameterLeak.symbols
Normal file
63
tests/baselines/reference/typeParameterLeak.symbols
Normal file
@ -0,0 +1,63 @@
|
||||
=== tests/cases/compiler/typeParameterLeak.ts ===
|
||||
// Repro from #35655
|
||||
|
||||
interface Box<T> { data: T }
|
||||
>Box : Symbol(Box, Decl(typeParameterLeak.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(typeParameterLeak.ts, 2, 14))
|
||||
>data : Symbol(Box.data, Decl(typeParameterLeak.ts, 2, 18))
|
||||
>T : Symbol(T, Decl(typeParameterLeak.ts, 2, 14))
|
||||
|
||||
type BoxTypes = Box<{ x: string }> | Box<{ y: string }>;
|
||||
>BoxTypes : Symbol(BoxTypes, Decl(typeParameterLeak.ts, 2, 28))
|
||||
>Box : Symbol(Box, Decl(typeParameterLeak.ts, 0, 0))
|
||||
>x : Symbol(x, Decl(typeParameterLeak.ts, 3, 21))
|
||||
>Box : Symbol(Box, Decl(typeParameterLeak.ts, 0, 0))
|
||||
>y : Symbol(y, Decl(typeParameterLeak.ts, 3, 42))
|
||||
|
||||
type BoxFactoryFactory<TBox> = TBox extends Box<infer T> ? {
|
||||
>BoxFactoryFactory : Symbol(BoxFactoryFactory, Decl(typeParameterLeak.ts, 3, 56))
|
||||
>TBox : Symbol(TBox, Decl(typeParameterLeak.ts, 5, 23))
|
||||
>TBox : Symbol(TBox, Decl(typeParameterLeak.ts, 5, 23))
|
||||
>Box : Symbol(Box, Decl(typeParameterLeak.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(typeParameterLeak.ts, 5, 53))
|
||||
|
||||
(arg: T): BoxFactory<TBox> | undefined
|
||||
>arg : Symbol(arg, Decl(typeParameterLeak.ts, 6, 3))
|
||||
>T : Symbol(T, Decl(typeParameterLeak.ts, 5, 53))
|
||||
>BoxFactory : Symbol(BoxFactory, Decl(typeParameterLeak.ts, 7, 10))
|
||||
>TBox : Symbol(TBox, Decl(typeParameterLeak.ts, 5, 23))
|
||||
|
||||
} : never;
|
||||
|
||||
interface BoxFactory<A> {
|
||||
>BoxFactory : Symbol(BoxFactory, Decl(typeParameterLeak.ts, 7, 10))
|
||||
>A : Symbol(A, Decl(typeParameterLeak.ts, 9, 21))
|
||||
|
||||
getBox(): A,
|
||||
>getBox : Symbol(BoxFactory.getBox, Decl(typeParameterLeak.ts, 9, 25))
|
||||
>A : Symbol(A, Decl(typeParameterLeak.ts, 9, 21))
|
||||
}
|
||||
|
||||
declare const f: BoxFactoryFactory<BoxTypes>;
|
||||
>f : Symbol(f, Decl(typeParameterLeak.ts, 13, 13))
|
||||
>BoxFactoryFactory : Symbol(BoxFactoryFactory, Decl(typeParameterLeak.ts, 3, 56))
|
||||
>BoxTypes : Symbol(BoxTypes, Decl(typeParameterLeak.ts, 2, 28))
|
||||
|
||||
const b = f({ x: "", y: "" })?.getBox();
|
||||
>b : Symbol(b, Decl(typeParameterLeak.ts, 14, 5))
|
||||
>f({ x: "", y: "" })?.getBox : Symbol(BoxFactory.getBox, Decl(typeParameterLeak.ts, 9, 25), Decl(typeParameterLeak.ts, 9, 25))
|
||||
>f : Symbol(f, Decl(typeParameterLeak.ts, 13, 13))
|
||||
>x : Symbol(x, Decl(typeParameterLeak.ts, 14, 13))
|
||||
>y : Symbol(y, Decl(typeParameterLeak.ts, 14, 20))
|
||||
>getBox : Symbol(BoxFactory.getBox, Decl(typeParameterLeak.ts, 9, 25), Decl(typeParameterLeak.ts, 9, 25))
|
||||
|
||||
if (b) {
|
||||
>b : Symbol(b, Decl(typeParameterLeak.ts, 14, 5))
|
||||
|
||||
const x = b.data;
|
||||
>x : Symbol(x, Decl(typeParameterLeak.ts, 16, 7))
|
||||
>b.data : Symbol(Box.data, Decl(typeParameterLeak.ts, 2, 18), Decl(typeParameterLeak.ts, 2, 18))
|
||||
>b : Symbol(b, Decl(typeParameterLeak.ts, 14, 5))
|
||||
>data : Symbol(Box.data, Decl(typeParameterLeak.ts, 2, 18), Decl(typeParameterLeak.ts, 2, 18))
|
||||
}
|
||||
|
||||
50
tests/baselines/reference/typeParameterLeak.types
Normal file
50
tests/baselines/reference/typeParameterLeak.types
Normal file
@ -0,0 +1,50 @@
|
||||
=== tests/cases/compiler/typeParameterLeak.ts ===
|
||||
// Repro from #35655
|
||||
|
||||
interface Box<T> { data: T }
|
||||
>data : T
|
||||
|
||||
type BoxTypes = Box<{ x: string }> | Box<{ y: string }>;
|
||||
>BoxTypes : BoxTypes
|
||||
>x : string
|
||||
>y : string
|
||||
|
||||
type BoxFactoryFactory<TBox> = TBox extends Box<infer T> ? {
|
||||
>BoxFactoryFactory : BoxFactoryFactory<TBox>
|
||||
|
||||
(arg: T): BoxFactory<TBox> | undefined
|
||||
>arg : T
|
||||
|
||||
} : never;
|
||||
|
||||
interface BoxFactory<A> {
|
||||
getBox(): A,
|
||||
>getBox : () => A
|
||||
}
|
||||
|
||||
declare const f: BoxFactoryFactory<BoxTypes>;
|
||||
>f : ((arg: { x: string; }) => BoxFactory<Box<{ x: string; }>> | undefined) | ((arg: { y: string; }) => BoxFactory<Box<{ y: string; }>> | undefined)
|
||||
|
||||
const b = f({ x: "", y: "" })?.getBox();
|
||||
>b : Box<{ x: string; }> | Box<{ y: string; }> | undefined
|
||||
>f({ x: "", y: "" })?.getBox() : Box<{ x: string; }> | Box<{ y: string; }> | undefined
|
||||
>f({ x: "", y: "" })?.getBox : (() => Box<{ x: string; }>) | (() => Box<{ y: string; }>) | undefined
|
||||
>f({ x: "", y: "" }) : BoxFactory<Box<{ x: string; }>> | BoxFactory<Box<{ y: string; }>> | undefined
|
||||
>f : ((arg: { x: string; }) => BoxFactory<Box<{ x: string; }>> | undefined) | ((arg: { y: string; }) => BoxFactory<Box<{ y: string; }>> | undefined)
|
||||
>{ x: "", y: "" } : { x: string; y: string; }
|
||||
>x : string
|
||||
>"" : ""
|
||||
>y : string
|
||||
>"" : ""
|
||||
>getBox : (() => Box<{ x: string; }>) | (() => Box<{ y: string; }>) | undefined
|
||||
|
||||
if (b) {
|
||||
>b : Box<{ x: string; }> | Box<{ y: string; }> | undefined
|
||||
|
||||
const x = b.data;
|
||||
>x : { x: string; } | { y: string; }
|
||||
>b.data : { x: string; } | { y: string; }
|
||||
>b : BoxTypes
|
||||
>data : { x: string; } | { y: string; }
|
||||
}
|
||||
|
||||
20
tests/cases/compiler/typeParameterLeak.ts
Normal file
20
tests/cases/compiler/typeParameterLeak.ts
Normal file
@ -0,0 +1,20 @@
|
||||
// @strict: true
|
||||
|
||||
// Repro from #35655
|
||||
|
||||
interface Box<T> { data: T }
|
||||
type BoxTypes = Box<{ x: string }> | Box<{ y: string }>;
|
||||
|
||||
type BoxFactoryFactory<TBox> = TBox extends Box<infer T> ? {
|
||||
(arg: T): BoxFactory<TBox> | undefined
|
||||
} : never;
|
||||
|
||||
interface BoxFactory<A> {
|
||||
getBox(): A,
|
||||
}
|
||||
|
||||
declare const f: BoxFactoryFactory<BoxTypes>;
|
||||
const b = f({ x: "", y: "" })?.getBox();
|
||||
if (b) {
|
||||
const x = b.data;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user