Skip to content

Commit 431937b

Browse files
Copilotjakebailey
andauthored
Fix spurious _N suffix on type parameters of sibling object-literal methods in declaration emit (#3969)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: jakebailey <5341706+jakebailey@users.noreply.github.com>
1 parent fd881b4 commit 431937b

6 files changed

Lines changed: 144 additions & 3 deletions

internal/checker/pseudotypenodebuilder.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,11 +203,11 @@ func (b *NodeBuilderImpl) pseudoTypeToNode(t *pseudochecker.PseudoType) *ast.Nod
203203
if isConst || (e.Kind == pseudochecker.PseudoObjectElementKindPropertyAssignment && e.AsPseudoPropertyAssignment().Readonly) {
204204
modifiers = b.f.NewModifierList([]*ast.Node{b.f.NewModifier(ast.KindReadonlyKeyword)})
205205
}
206+
var cleanup func()
206207
if e.Kind != pseudochecker.PseudoObjectElementKindPropertyAssignment {
207208
signature := b.ch.getSignatureFromDeclaration(e.Signature())
208209
expandedParams := b.ch.getExpandedParameters(signature, true /*skipUnionExpanding*/)[0]
209-
cleanup := b.enterNewScope(e.Signature(), expandedParams, signature.typeParameters, signature.parameters, signature.mapper)
210-
defer cleanup()
210+
cleanup = b.enterNewScope(e.Signature(), expandedParams, signature.typeParameters, signature.parameters, signature.mapper)
211211
}
212212
var newProp *ast.Node
213213
switch e.Kind {
@@ -279,6 +279,9 @@ func (b *NodeBuilderImpl) pseudoTypeToNode(t *pseudochecker.PseudoType) *ast.Nod
279279
b.e.SetCommentRange(newProp, e.Name.Parent.Loc)
280280
}
281281
newElements = append(newElements, newProp)
282+
if cleanup != nil {
283+
cleanup()
284+
}
282285
}
283286
result := b.f.NewTypeLiteralNode(b.f.NewNodeList(newElements))
284287
if b.ctx.flags&nodebuilder.FlagsMultilineObjectLiterals == 0 {

testdata/baselines/reference/compiler/declarationEmitConstObjectLiteralGenericMethod1.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,5 @@ export const obj1 = {
2525
//// [declarationEmitConstObjectLiteralGenericMethod1.d.ts]
2626
export declare const obj1: {
2727
id<T>(value: T): T;
28-
pair<T_1>(left: T_1, right: T_1): T_1[];
28+
pair<T>(left: T, right: T): T[];
2929
};
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
//// [tests/cases/compiler/declarationEmitObjectLiteralMethodGenericNoSuffix.ts] ////
2+
3+
//// [declarationEmitObjectLiteralMethodGenericNoSuffix.ts]
4+
export const o = {
5+
foo<M extends string>(): void { },
6+
bar<M extends string>(): void { },
7+
};
8+
9+
export const o2 = {
10+
foo<T>(value: T): T { return value; },
11+
bar<T>(value: T): T { return value; },
12+
baz<T, U>(a: T, b: U): [T, U] { return [a, b]; },
13+
};
14+
15+
16+
//// [declarationEmitObjectLiteralMethodGenericNoSuffix.js]
17+
export const o = {
18+
foo() { },
19+
bar() { },
20+
};
21+
export const o2 = {
22+
foo(value) { return value; },
23+
bar(value) { return value; },
24+
baz(a, b) { return [a, b]; },
25+
};
26+
27+
28+
//// [declarationEmitObjectLiteralMethodGenericNoSuffix.d.ts]
29+
export declare const o: {
30+
foo<M extends string>(): void;
31+
bar<M extends string>(): void;
32+
};
33+
export declare const o2: {
34+
foo<T>(value: T): T;
35+
bar<T>(value: T): T;
36+
baz<T, U>(a: T, b: U): [T, U];
37+
};
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
//// [tests/cases/compiler/declarationEmitObjectLiteralMethodGenericNoSuffix.ts] ////
2+
3+
=== declarationEmitObjectLiteralMethodGenericNoSuffix.ts ===
4+
export const o = {
5+
>o : Symbol(o, Decl(declarationEmitObjectLiteralMethodGenericNoSuffix.ts, 0, 12))
6+
7+
foo<M extends string>(): void { },
8+
>foo : Symbol(foo, Decl(declarationEmitObjectLiteralMethodGenericNoSuffix.ts, 0, 18))
9+
>M : Symbol(M, Decl(declarationEmitObjectLiteralMethodGenericNoSuffix.ts, 1, 8))
10+
11+
bar<M extends string>(): void { },
12+
>bar : Symbol(bar, Decl(declarationEmitObjectLiteralMethodGenericNoSuffix.ts, 1, 38))
13+
>M : Symbol(M, Decl(declarationEmitObjectLiteralMethodGenericNoSuffix.ts, 2, 8))
14+
15+
};
16+
17+
export const o2 = {
18+
>o2 : Symbol(o2, Decl(declarationEmitObjectLiteralMethodGenericNoSuffix.ts, 5, 12))
19+
20+
foo<T>(value: T): T { return value; },
21+
>foo : Symbol(foo, Decl(declarationEmitObjectLiteralMethodGenericNoSuffix.ts, 5, 19))
22+
>T : Symbol(T, Decl(declarationEmitObjectLiteralMethodGenericNoSuffix.ts, 6, 8))
23+
>value : Symbol(value, Decl(declarationEmitObjectLiteralMethodGenericNoSuffix.ts, 6, 11))
24+
>T : Symbol(T, Decl(declarationEmitObjectLiteralMethodGenericNoSuffix.ts, 6, 8))
25+
>T : Symbol(T, Decl(declarationEmitObjectLiteralMethodGenericNoSuffix.ts, 6, 8))
26+
>value : Symbol(value, Decl(declarationEmitObjectLiteralMethodGenericNoSuffix.ts, 6, 11))
27+
28+
bar<T>(value: T): T { return value; },
29+
>bar : Symbol(bar, Decl(declarationEmitObjectLiteralMethodGenericNoSuffix.ts, 6, 42))
30+
>T : Symbol(T, Decl(declarationEmitObjectLiteralMethodGenericNoSuffix.ts, 7, 8))
31+
>value : Symbol(value, Decl(declarationEmitObjectLiteralMethodGenericNoSuffix.ts, 7, 11))
32+
>T : Symbol(T, Decl(declarationEmitObjectLiteralMethodGenericNoSuffix.ts, 7, 8))
33+
>T : Symbol(T, Decl(declarationEmitObjectLiteralMethodGenericNoSuffix.ts, 7, 8))
34+
>value : Symbol(value, Decl(declarationEmitObjectLiteralMethodGenericNoSuffix.ts, 7, 11))
35+
36+
baz<T, U>(a: T, b: U): [T, U] { return [a, b]; },
37+
>baz : Symbol(baz, Decl(declarationEmitObjectLiteralMethodGenericNoSuffix.ts, 7, 42))
38+
>T : Symbol(T, Decl(declarationEmitObjectLiteralMethodGenericNoSuffix.ts, 8, 8))
39+
>U : Symbol(U, Decl(declarationEmitObjectLiteralMethodGenericNoSuffix.ts, 8, 10))
40+
>a : Symbol(a, Decl(declarationEmitObjectLiteralMethodGenericNoSuffix.ts, 8, 14))
41+
>T : Symbol(T, Decl(declarationEmitObjectLiteralMethodGenericNoSuffix.ts, 8, 8))
42+
>b : Symbol(b, Decl(declarationEmitObjectLiteralMethodGenericNoSuffix.ts, 8, 19))
43+
>U : Symbol(U, Decl(declarationEmitObjectLiteralMethodGenericNoSuffix.ts, 8, 10))
44+
>T : Symbol(T, Decl(declarationEmitObjectLiteralMethodGenericNoSuffix.ts, 8, 8))
45+
>U : Symbol(U, Decl(declarationEmitObjectLiteralMethodGenericNoSuffix.ts, 8, 10))
46+
>a : Symbol(a, Decl(declarationEmitObjectLiteralMethodGenericNoSuffix.ts, 8, 14))
47+
>b : Symbol(b, Decl(declarationEmitObjectLiteralMethodGenericNoSuffix.ts, 8, 19))
48+
49+
};
50+
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//// [tests/cases/compiler/declarationEmitObjectLiteralMethodGenericNoSuffix.ts] ////
2+
3+
=== declarationEmitObjectLiteralMethodGenericNoSuffix.ts ===
4+
export const o = {
5+
>o : { foo<M extends string>(): void; bar<M extends string>(): void; }
6+
>{ foo<M extends string>(): void { }, bar<M extends string>(): void { },} : { foo<M extends string>(): void; bar<M extends string>(): void; }
7+
8+
foo<M extends string>(): void { },
9+
>foo : <M extends string>() => void
10+
11+
bar<M extends string>(): void { },
12+
>bar : <M extends string>() => void
13+
14+
};
15+
16+
export const o2 = {
17+
>o2 : { foo<T>(value: T): T; bar<T>(value: T): T; baz<T, U>(a: T, b: U): [T, U]; }
18+
>{ foo<T>(value: T): T { return value; }, bar<T>(value: T): T { return value; }, baz<T, U>(a: T, b: U): [T, U] { return [a, b]; },} : { foo<T>(value: T): T; bar<T>(value: T): T; baz<T, U>(a: T, b: U): [T, U]; }
19+
20+
foo<T>(value: T): T { return value; },
21+
>foo : <T>(value: T) => T
22+
>value : T
23+
>value : T
24+
25+
bar<T>(value: T): T { return value; },
26+
>bar : <T>(value: T) => T
27+
>value : T
28+
>value : T
29+
30+
baz<T, U>(a: T, b: U): [T, U] { return [a, b]; },
31+
>baz : <T, U>(a: T, b: U) => [T, U]
32+
>a : T
33+
>b : U
34+
>[a, b] : [T, U]
35+
>a : T
36+
>b : U
37+
38+
};
39+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// @declaration: true
2+
3+
export const o = {
4+
foo<M extends string>(): void { },
5+
bar<M extends string>(): void { },
6+
};
7+
8+
export const o2 = {
9+
foo<T>(value: T): T { return value; },
10+
bar<T>(value: T): T { return value; },
11+
baz<T, U>(a: T, b: U): [T, U] { return [a, b]; },
12+
};

0 commit comments

Comments
 (0)