Repository: microsoft/typescript-go (go)

Issue:
bigint literal creates invalid type declaration
With the following setup:

tsgo compiled from commit `2aa0eb5d92ba30e24710a5fa95a8781ae8ef285a`

tsconfig.json
```json
{
    "compilerOptions": {
        "target": "ES2020",
        "outDir": "./dist",
        "declaration": true,
    }
}
```

bug.ts
```ts
export const X = 0n;
```

The emitted declarations are invalid:
```
> rm -rf dist && tsgo && cat dist/bug.d.ts
export declare const X = ;
```



Pull request:
fix(1250): fix bigint literal type declaration emit
Fixes #1250

Patch:
diff --git a/internal/checker/emitresolver.go b/internal/checker/emitresolver.go
index 0939def9d..4be45bc03 100644
--- a/internal/checker/emitresolver.go
+++ b/internal/checker/emitresolver.go
@@ -900,12 +900,10 @@ func (r *emitResolver) CreateLiteralConstValue(emitContext *printer.EmitContext,
 	if t.flags&TypeFlagsLiteral == 0 {
 		return nil // non-literal type
 	}
-	literalValue := t.AsLiteralType().value
-	switch literalValue.(type) {
+	switch value := t.AsLiteralType().value.(type) {
 	case string:
-		return emitContext.Factory.NewStringLiteral(literalValue.(string))
+		return emitContext.Factory.NewStringLiteral(value)
 	case jsnum.Number:
-		value := literalValue.(jsnum.Number)
 		if value.Abs() != value {
 			// negative
 			return emitContext.Factory.NewPrefixUnaryExpression(
@@ -915,20 +913,13 @@ func (r *emitResolver) CreateLiteralConstValue(emitContext *printer.EmitContext,
 		}
 		return emitContext.Factory.NewNumericLiteral(value.String())
 	case jsnum.PseudoBigInt:
-		value := literalValue.(jsnum.PseudoBigInt)
-		if value.Negative {
-			// negative
-			return emitContext.Factory.NewPrefixUnaryExpression(
-				ast.KindMinusToken,
-				emitContext.Factory.NewBigIntLiteral(value.Base10Value),
-			)
-		}
-		return emitContext.Factory.NewNumericLiteral(value.Base10Value)
+		return emitContext.Factory.NewBigIntLiteral(pseudoBigIntToString(value) + "n")
 	case bool:
-		if literalValue.(bool) {
-			return emitContext.Factory.NewKeywordExpression(ast.KindTrueKeyword)
+		kind := ast.KindFalseKeyword
+		if value {
+			kind = ast.KindTrueKeyword
 		}
-		return emitContext.Factory.NewKeywordExpression(ast.KindFalseKeyword)
+		return emitContext.Factory.NewKeywordExpression(kind)
 	}
 	panic("unhandled literal const value kind")
 }


Test patch:
diff --git a/testdata/baselines/reference/compiler/declarationEmitBigInt.js b/testdata/baselines/reference/compiler/declarationEmitBigInt.js
new file mode 100644
index 000000000..9c47f7441
--- /dev/null
+++ b/testdata/baselines/reference/compiler/declarationEmitBigInt.js
@@ -0,0 +1,21 @@
+//// [tests/cases/compiler/declarationEmitBigInt.ts] ////
+
+//// [a.ts]
+export const a = 0n;
+export const b = 10n;
+export const c = -0n;
+export const d = -10n;
+
+
+//// [a.js]
+export const a = 0n;
+export const b = 10n;
+export const c = -0n;
+export const d = -10n;
+
+
+//// [a.d.ts]
+export declare const a = 0n;
+export declare const b = 10n;
+export declare const c = 0n;
+export declare const d = -10n;
diff --git a/testdata/baselines/reference/compiler/declarationEmitBigInt.symbols b/testdata/baselines/reference/compiler/declarationEmitBigInt.symbols
new file mode 100644
index 000000000..3f513f717
--- /dev/null
+++ b/testdata/baselines/reference/compiler/declarationEmitBigInt.symbols
@@ -0,0 +1,15 @@
+//// [tests/cases/compiler/declarationEmitBigInt.ts] ////
+
+=== a.ts ===
+export const a = 0n;
+>a : Symbol(a, Decl(a.ts, 0, 12))
+
+export const b = 10n;
+>b : Symbol(b, Decl(a.ts, 1, 12))
+
+export const c = -0n;
+>c : Symbol(c, Decl(a.ts, 2, 12))
+
+export const d = -10n;
+>d : Symbol(d, Decl(a.ts, 3, 12))
+
diff --git a/testdata/baselines/reference/compiler/declarationEmitBigInt.types b/testdata/baselines/reference/compiler/declarationEmitBigInt.types
new file mode 100644
index 000000000..2ea33de57
--- /dev/null
+++ b/testdata/baselines/reference/compiler/declarationEmitBigInt.types
@@ -0,0 +1,21 @@
+//// [tests/cases/compiler/declarationEmitBigInt.ts] ////
+
+=== a.ts ===
+export const a = 0n;
+>a : 0n
+>0n : 0n
+
+export const b = 10n;
+>b : 10n
+>10n : 10n
+
+export const c = -0n;
+>c : 0n
+>-0n : 0n
+>0n : 0n
+
+export const d = -10n;
+>d : -10n
+>-10n : -10n
+>10n : 10n
+
diff --git a/testdata/baselines/reference/submodule/compiler/bigintWithLib.js b/testdata/baselines/reference/submodule/compiler/bigintWithLib.js
index 34eee0837..5983e3168 100644
--- a/testdata/baselines/reference/submodule/compiler/bigintWithLib.js
+++ b/testdata/baselines/reference/submodule/compiler/bigintWithLib.js
@@ -134,7 +134,7 @@ declare let bigUintArray: BigUint64Array;
 // Test added DataView methods
 declare const dataView: DataView<ArrayBuffer>;
 // Test emitted declarations files
-declare const w = 12; // should emit as const w = 12n
-declare const x = -12; // should emit as const x = -12n
+declare const w = 12n; // should emit as const w = 12n
+declare const x = -12n; // should emit as const x = -12n
 declare const y: 12n; // should emit type 12n
 declare let z: bigint; // should emit type bigint in declaration file
diff --git a/testdata/baselines/reference/submodule/compiler/bigintWithLib.js.diff b/testdata/baselines/reference/submodule/compiler/bigintWithLib.js.diff
index 699daf3b5..dcea08419 100644
--- a/testdata/baselines/reference/submodule/compiler/bigintWithLib.js.diff
+++ b/testdata/baselines/reference/submodule/compiler/bigintWithLib.js.diff
@@ -20,7 +20,7 @@
 -declare const y: 12n;
 -declare let z: bigint;
 +// Test emitted declarations files
-+declare const w = 12; // should emit as const w = 12n
-+declare const x = -12; // should emit as const x = -12n
++declare const w = 12n; // should emit as const w = 12n
++declare const x = -12n; // should emit as const x = -12n
 +declare const y: 12n; // should emit type 12n
 +declare let z: bigint; // should emit type bigint in declaration file
\ No newline at end of file
diff --git a/testdata/baselines/reference/submodule/compiler/isolatedDeclarationErrorsExpressions.js b/testdata/baselines/reference/submodule/compiler/isolatedDeclarationErrorsExpressions.js
index e576a16eb..d6f332839 100644
--- a/testdata/baselines/reference/submodule/compiler/isolatedDeclarationErrorsExpressions.js
+++ b/testdata/baselines/reference/submodule/compiler/isolatedDeclarationErrorsExpressions.js
@@ -242,10 +242,10 @@ export declare const numberConst = 1;
 export declare const numberConstBad1: number;
 export declare const numberConstBad2: number;
 export declare const numberConstBad3 = 1;
-export declare const bigIntConst = 1;
+export declare const bigIntConst = 1n;
 export declare const bigIntConstBad1: bigint;
 export declare const bigIntConstBad2: bigint;
-export declare const bigIntConstBad3 = 1;
+export declare const bigIntConstBad3 = 1n;
 export declare const stringConst = "s";
 export declare const stringConstBad: string;
 // These are just strings
diff --git a/testdata/baselines/reference/submodule/compiler/isolatedDeclarationErrorsExpressions.js.diff b/testdata/baselines/reference/submodule/compiler/isolatedDeclarationErrorsExpressions.js.diff
index 82bcab4e7..7cbfdbb9b 100644
--- a/testdata/baselines/reference/submodule/compiler/isolatedDeclarationErrorsExpressions.js.diff
+++ b/testdata/baselines/reference/submodule/compiler/isolatedDeclarationErrorsExpressions.js.diff
@@ -11,10 +11,10 @@
 +export declare const numberConstBad1: number;
 +export declare const numberConstBad2: number;
 +export declare const numberConstBad3 = 1;
-+export declare const bigIntConst = 1;
++export declare const bigIntConst = 1n;
 +export declare const bigIntConstBad1: bigint;
 +export declare const bigIntConstBad2: bigint;
-+export declare const bigIntConstBad3 = 1;
++export declare const bigIntConstBad3 = 1n;
 +export declare const stringConst = "s";
 +export declare const stringConstBad: string;
 +// These are just strings
diff --git a/testdata/baselines/reference/submodule/compiler/isolatedDeclarationsLiterals.js b/testdata/baselines/reference/submodule/compiler/isolatedDeclarationsLiterals.js
index 71c6e280c..24f3eba44 100644
--- a/testdata/baselines/reference/submodule/compiler/isolatedDeclarationsLiterals.js
+++ b/testdata/baselines/reference/submodule/compiler/isolatedDeclarationsLiterals.js
@@ -154,8 +154,8 @@ export declare const oneOctal = 1;
 export declare const oneHex = 1;
 export declare const pOne = 1;
 export declare const mOne = -1;
-export declare const onen = 1;
-export declare const mOnen = -1;
+export declare const onen = 1n;
+export declare const mOnen = -1n;
 export declare const oneStrDoubleQuote = "1";
 export declare const oneStrSingleQuote = "1";
 export declare const oneStrTemplate = "1";
diff --git a/testdata/baselines/reference/submodule/compiler/isolatedDeclarationsLiterals.js.diff b/testdata/baselines/reference/submodule/compiler/isolatedDeclarationsLiterals.js.diff
deleted file mode 100644
index e62b0959d..000000000
--- a/testdata/baselines/reference/submodule/compiler/isolatedDeclarationsLiterals.js.diff
+++ /dev/null
@@ -1,13 +0,0 @@
---- old.isolatedDeclarationsLiterals.js
-+++ new.isolatedDeclarationsLiterals.js
-@@= skipped -153, +153 lines =@@
- export declare const oneHex = 1;
- export declare const pOne = 1;
- export declare const mOne = -1;
--export declare const onen = 1n;
--export declare const mOnen = -1n;
-+export declare const onen = 1;
-+export declare const mOnen = -1;
- export declare const oneStrDoubleQuote = "1";
- export declare const oneStrSingleQuote = "1";
- export declare const oneStrTemplate = "1";
\ No newline at end of file
diff --git a/testdata/tests/cases/compiler/declarationEmitBigInt.ts b/testdata/tests/cases/compiler/declarationEmitBigInt.ts
new file mode 100644
index 000000000..c8cacebf1
--- /dev/null
+++ b/testdata/tests/cases/compiler/declarationEmitBigInt.ts
@@ -0,0 +1,7 @@
+// @target: es2020
+// @declaration: true
+// @filename: a.ts
+export const a = 0n;
+export const b = 10n;
+export const c = -0n;
+export const d = -10n;