Skip to content

Commit a980d86

Browse files
Copilotjakebailey
andauthored
Elide in/out variance modifiers from emitted JS (#4156)
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 b3f6abf commit a980d86

6 files changed

Lines changed: 140 additions & 0 deletions

File tree

internal/transformers/tstransforms/typeeraser.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,16 @@ func (tx *TypeEraserTransformer) visit(node *ast.Node) *ast.Node {
9696
ast.KindIndexSignature:
9797
return nil
9898

99+
case ast.KindInKeyword, ast.KindOutKeyword:
100+
// TypeScript `in`/`out` variance modifiers are elided. These keywords are only
101+
// meaningful as modifiers on type parameters (which are themselves elided), but they may
102+
// appear as a grammar error on other declarations and must not leak into the emitted JS.
103+
// The `in` binary operator shares this token kind, so only elide when used as a modifier.
104+
if tx.parentNode == nil || !ast.IsBinaryExpression(tx.parentNode) {
105+
return nil
106+
}
107+
return tx.Visitor().VisitEachChild(node)
108+
99109
case ast.KindJSImportDeclaration:
100110
// reparsed commonjs are elided
101111
return nil
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
varianceModifiersOnClassMembers.ts(4,3): error TS1274: 'in' modifier can only appear on a type parameter of a class, interface or type alias
2+
varianceModifiersOnClassMembers.ts(5,3): error TS1274: 'out' modifier can only appear on a type parameter of a class, interface or type alias
3+
4+
5+
==== varianceModifiersOnClassMembers.ts (2 errors) ====
6+
// https://github.com/microsoft/typescript-go/issues/4123
7+
8+
class C {
9+
in x = 1;
10+
~~
11+
!!! error TS1274: 'in' modifier can only appear on a type parameter of a class, interface or type alias
12+
out y = 2;
13+
~~~
14+
!!! error TS1274: 'out' modifier can only appear on a type parameter of a class, interface or type alias
15+
}
16+
17+
const isIn = "x" in { x: 1 };
18+
for (const k in { x: 1 }) {
19+
console.log(k);
20+
}
21+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
//// [tests/cases/compiler/varianceModifiersOnClassMembers.ts] ////
2+
3+
//// [varianceModifiersOnClassMembers.ts]
4+
// https://github.com/microsoft/typescript-go/issues/4123
5+
6+
class C {
7+
in x = 1;
8+
out y = 2;
9+
}
10+
11+
const isIn = "x" in { x: 1 };
12+
for (const k in { x: 1 }) {
13+
console.log(k);
14+
}
15+
16+
17+
//// [varianceModifiersOnClassMembers.js]
18+
"use strict";
19+
// https://github.com/microsoft/typescript-go/issues/4123
20+
class C {
21+
x = 1;
22+
y = 2;
23+
}
24+
const isIn = "x" in { x: 1 };
25+
for (const k in { x: 1 }) {
26+
console.log(k);
27+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//// [tests/cases/compiler/varianceModifiersOnClassMembers.ts] ////
2+
3+
=== varianceModifiersOnClassMembers.ts ===
4+
// https://github.com/microsoft/typescript-go/issues/4123
5+
6+
class C {
7+
>C : Symbol(C, Decl(varianceModifiersOnClassMembers.ts, 0, 0))
8+
9+
in x = 1;
10+
>x : Symbol(C.x, Decl(varianceModifiersOnClassMembers.ts, 2, 9))
11+
12+
out y = 2;
13+
>y : Symbol(C.y, Decl(varianceModifiersOnClassMembers.ts, 3, 11))
14+
}
15+
16+
const isIn = "x" in { x: 1 };
17+
>isIn : Symbol(isIn, Decl(varianceModifiersOnClassMembers.ts, 7, 5))
18+
>x : Symbol(x, Decl(varianceModifiersOnClassMembers.ts, 7, 21))
19+
20+
for (const k in { x: 1 }) {
21+
>k : Symbol(k, Decl(varianceModifiersOnClassMembers.ts, 8, 10))
22+
>x : Symbol(x, Decl(varianceModifiersOnClassMembers.ts, 8, 17))
23+
24+
console.log(k);
25+
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
26+
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
27+
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
28+
>k : Symbol(k, Decl(varianceModifiersOnClassMembers.ts, 8, 10))
29+
}
30+
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//// [tests/cases/compiler/varianceModifiersOnClassMembers.ts] ////
2+
3+
=== varianceModifiersOnClassMembers.ts ===
4+
// https://github.com/microsoft/typescript-go/issues/4123
5+
6+
class C {
7+
>C : C
8+
9+
in x = 1;
10+
>x : number
11+
>1 : 1
12+
13+
out y = 2;
14+
>y : number
15+
>2 : 2
16+
}
17+
18+
const isIn = "x" in { x: 1 };
19+
>isIn : boolean
20+
>"x" in { x: 1 } : boolean
21+
>"x" : "x"
22+
>{ x: 1 } : { x: number; }
23+
>x : number
24+
>1 : 1
25+
26+
for (const k in { x: 1 }) {
27+
>k : string
28+
>{ x: 1 } : { x: number; }
29+
>x : number
30+
>1 : 1
31+
32+
console.log(k);
33+
>console.log(k) : void
34+
>console.log : (...data: any[]) => void
35+
>console : Console
36+
>log : (...data: any[]) => void
37+
>k : string
38+
}
39+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// @target: esnext
2+
3+
// https://github.com/microsoft/typescript-go/issues/4123
4+
5+
class C {
6+
in x = 1;
7+
out y = 2;
8+
}
9+
10+
const isIn = "x" in { x: 1 };
11+
for (const k in { x: 1 }) {
12+
console.log(k);
13+
}

0 commit comments

Comments
 (0)