diff --git a/src/compiler/transformers/declarations.ts b/src/compiler/transformers/declarations.ts index 02e6acd9dd816..e0ff6a154c534 100644 --- a/src/compiler/transformers/declarations.ts +++ b/src/compiler/transformers/declarations.ts @@ -1761,12 +1761,17 @@ export function transformDeclarations(context: TransformationContext) { return cleanup(transformVariableStatement(input)); } case SyntaxKind.EnumDeclaration: { - return cleanup(factory.updateEnumDeclaration(input, factory.createNodeArray(ensureModifiers(input)), input.name, factory.createNodeArray(mapDefined(input.members, m => { - if (shouldStripInternal(m)) return; - // Rewrite enum values to their constants, if available - const constValue = resolver.getConstantValue(m); - return preserveJsDoc(factory.updateEnumMember(m, m.name, constValue !== undefined ? typeof constValue === "string" ? factory.createStringLiteral(constValue) : factory.createNumericLiteral(constValue) : undefined), m); - })))); + return cleanup(factory.updateEnumDeclaration( + input, + factory.createNodeArray(ensureModifiers(input)), + input.name, + factory.createNodeArray(mapDefined(input.members, m => { + if (shouldStripInternal(m)) return; + // Rewrite enum values to their constants, if available + const constValue = resolver.getConstantValue(m); + return preserveJsDoc(factory.updateEnumMember(m, m.name, constValue !== undefined ? typeof constValue === "string" ? factory.createStringLiteral(constValue) : factory.createNumericLiteral(constValue) : undefined), m); + })), + )); } } // Anything left unhandled is an error, so this should be unreachable diff --git a/tests/baselines/reference/fakeInfinity1.errors.txt b/tests/baselines/reference/fakeInfinity1.errors.txt new file mode 100644 index 0000000000000..52fd2751609ed --- /dev/null +++ b/tests/baselines/reference/fakeInfinity1.errors.txt @@ -0,0 +1,29 @@ +fakeInfinity1.ts(17,1): error TS2322: Type 'number' is not assignable to type 'Infinity'. + + +==== fakeInfinity1.ts (1 errors) ==== + // These are not actually the real infinity. + export type PositiveInfinity = 1e999; + export type NegativeInfinity = -1e999; + + export type TypeOfInfinity = typeof Infinity; + export type TypeOfNaN = typeof NaN; + + type A = 1e999; + type B = 1e9999; + + declare let a: A; + declare let b: B; + + a = b; + b = a; + + a = Infinity; + ~ +!!! error TS2322: Type 'number' is not assignable to type 'Infinity'. + a = 1e999; + a = 1e9999; + + export type Oops = 123456789123456789123456789123456789123456789123456789; + export const oops = 123456789123456789123456789123456789123456789123456789; + \ No newline at end of file diff --git a/tests/baselines/reference/fakeInfinity1.js b/tests/baselines/reference/fakeInfinity1.js new file mode 100644 index 0000000000000..c28497a9fa3a0 --- /dev/null +++ b/tests/baselines/reference/fakeInfinity1.js @@ -0,0 +1,46 @@ +//// [tests/cases/compiler/fakeInfinity1.ts] //// + +//// [fakeInfinity1.ts] +// These are not actually the real infinity. +export type PositiveInfinity = 1e999; +export type NegativeInfinity = -1e999; + +export type TypeOfInfinity = typeof Infinity; +export type TypeOfNaN = typeof NaN; + +type A = 1e999; +type B = 1e9999; + +declare let a: A; +declare let b: B; + +a = b; +b = a; + +a = Infinity; +a = 1e999; +a = 1e9999; + +export type Oops = 123456789123456789123456789123456789123456789123456789; +export const oops = 123456789123456789123456789123456789123456789123456789; + + +//// [fakeInfinity1.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.oops = void 0; +a = b; +b = a; +a = Infinity; +a = 1e999; +a = 1e9999; +exports.oops = 123456789123456789123456789123456789123456789123456789; + + +//// [fakeInfinity1.d.ts] +export type PositiveInfinity = 1e999; +export type NegativeInfinity = -1e999; +export type TypeOfInfinity = typeof Infinity; +export type TypeOfNaN = typeof NaN; +export type Oops = 123456789123456789123456789123456789123456789123456789; +export declare const oops = 1.2345678912345678e+53; diff --git a/tests/baselines/reference/fakeInfinity1.symbols b/tests/baselines/reference/fakeInfinity1.symbols new file mode 100644 index 0000000000000..07cb183dae865 --- /dev/null +++ b/tests/baselines/reference/fakeInfinity1.symbols @@ -0,0 +1,56 @@ +//// [tests/cases/compiler/fakeInfinity1.ts] //// + +=== fakeInfinity1.ts === +// These are not actually the real infinity. +export type PositiveInfinity = 1e999; +>PositiveInfinity : Symbol(PositiveInfinity, Decl(fakeInfinity1.ts, 0, 0)) + +export type NegativeInfinity = -1e999; +>NegativeInfinity : Symbol(NegativeInfinity, Decl(fakeInfinity1.ts, 1, 37)) + +export type TypeOfInfinity = typeof Infinity; +>TypeOfInfinity : Symbol(TypeOfInfinity, Decl(fakeInfinity1.ts, 2, 38)) +>Infinity : Symbol(Infinity, Decl(lib.es5.d.ts, --, --)) + +export type TypeOfNaN = typeof NaN; +>TypeOfNaN : Symbol(TypeOfNaN, Decl(fakeInfinity1.ts, 4, 45)) +>NaN : Symbol(NaN, Decl(lib.es5.d.ts, --, --)) + +type A = 1e999; +>A : Symbol(A, Decl(fakeInfinity1.ts, 5, 35)) + +type B = 1e9999; +>B : Symbol(B, Decl(fakeInfinity1.ts, 7, 15)) + +declare let a: A; +>a : Symbol(a, Decl(fakeInfinity1.ts, 10, 11)) +>A : Symbol(A, Decl(fakeInfinity1.ts, 5, 35)) + +declare let b: B; +>b : Symbol(b, Decl(fakeInfinity1.ts, 11, 11)) +>B : Symbol(B, Decl(fakeInfinity1.ts, 7, 15)) + +a = b; +>a : Symbol(a, Decl(fakeInfinity1.ts, 10, 11)) +>b : Symbol(b, Decl(fakeInfinity1.ts, 11, 11)) + +b = a; +>b : Symbol(b, Decl(fakeInfinity1.ts, 11, 11)) +>a : Symbol(a, Decl(fakeInfinity1.ts, 10, 11)) + +a = Infinity; +>a : Symbol(a, Decl(fakeInfinity1.ts, 10, 11)) +>Infinity : Symbol(Infinity, Decl(lib.es5.d.ts, --, --)) + +a = 1e999; +>a : Symbol(a, Decl(fakeInfinity1.ts, 10, 11)) + +a = 1e9999; +>a : Symbol(a, Decl(fakeInfinity1.ts, 10, 11)) + +export type Oops = 123456789123456789123456789123456789123456789123456789; +>Oops : Symbol(Oops, Decl(fakeInfinity1.ts, 18, 11)) + +export const oops = 123456789123456789123456789123456789123456789123456789; +>oops : Symbol(oops, Decl(fakeInfinity1.ts, 21, 12)) + diff --git a/tests/baselines/reference/fakeInfinity1.types b/tests/baselines/reference/fakeInfinity1.types new file mode 100644 index 0000000000000..0d5f3d1aa4f37 --- /dev/null +++ b/tests/baselines/reference/fakeInfinity1.types @@ -0,0 +1,64 @@ +//// [tests/cases/compiler/fakeInfinity1.ts] //// + +=== fakeInfinity1.ts === +// These are not actually the real infinity. +export type PositiveInfinity = 1e999; +>PositiveInfinity : Infinity + +export type NegativeInfinity = -1e999; +>NegativeInfinity : -Infinity +>-1e999 : -Infinity +>1e999 : Infinity + +export type TypeOfInfinity = typeof Infinity; +>TypeOfInfinity : number +>Infinity : number + +export type TypeOfNaN = typeof NaN; +>TypeOfNaN : number +>NaN : number + +type A = 1e999; +>A : Infinity + +type B = 1e9999; +>B : Infinity + +declare let a: A; +>a : Infinity + +declare let b: B; +>b : Infinity + +a = b; +>a = b : Infinity +>a : Infinity +>b : Infinity + +b = a; +>b = a : Infinity +>b : Infinity +>a : Infinity + +a = Infinity; +>a = Infinity : number +>a : Infinity +>Infinity : number + +a = 1e999; +>a = 1e999 : Infinity +>a : Infinity +>1e999 : Infinity + +a = 1e9999; +>a = 1e9999 : Infinity +>a : Infinity +>1e9999 : Infinity + +export type Oops = 123456789123456789123456789123456789123456789123456789; +>Oops : 1.2345678912345678e+53 + +export const oops = 123456789123456789123456789123456789123456789123456789; +>oops : 1.2345678912345678e+53 +>123456789123456789123456789123456789123456789123456789 : 1.2345678912345678e+53 + diff --git a/tests/baselines/reference/fakeInfinity2.js b/tests/baselines/reference/fakeInfinity2.js new file mode 100644 index 0000000000000..779b0f421d988 --- /dev/null +++ b/tests/baselines/reference/fakeInfinity2.js @@ -0,0 +1,62 @@ +//// [tests/cases/compiler/fakeInfinity2.ts] //// + +//// [fakeInfinity2.ts] +export enum Foo { + A = 1e999, + B = -1e999, +} + +namespace X { + type A = 1e999; + type B = 2e999; + + export function f(): A { + throw new Error() + } +} + +export const m = X.f(); + + +//// [fakeInfinity2.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.m = exports.Foo = void 0; +var Foo; +(function (Foo) { + Foo[Foo["A"] = Infinity] = "A"; + Foo[Foo["B"] = -Infinity] = "B"; +})(Foo || (exports.Foo = Foo = {})); +var X; +(function (X) { + function f() { + throw new Error(); + } + X.f = f; +})(X || (X = {})); +exports.m = X.f(); + + +//// [fakeInfinity2.d.ts] +export declare enum Foo { + A = Infinity, + B = -Infinity +} +export declare const m: Infinity; + + +//// [DtsFileErrors] + + +fakeInfinity2.d.ts(5,25): error TS2749: 'Infinity' refers to a value, but is being used as a type here. Did you mean 'typeof Infinity'? + + +==== fakeInfinity2.d.ts (1 errors) ==== + export declare enum Foo { + A = Infinity, + B = -Infinity + } + export declare const m: Infinity; + ~~~~~~~~ +!!! error TS2749: 'Infinity' refers to a value, but is being used as a type here. Did you mean 'typeof Infinity'? + \ No newline at end of file diff --git a/tests/baselines/reference/fakeInfinity2.symbols b/tests/baselines/reference/fakeInfinity2.symbols new file mode 100644 index 0000000000000..3071165542447 --- /dev/null +++ b/tests/baselines/reference/fakeInfinity2.symbols @@ -0,0 +1,37 @@ +//// [tests/cases/compiler/fakeInfinity2.ts] //// + +=== fakeInfinity2.ts === +export enum Foo { +>Foo : Symbol(Foo, Decl(fakeInfinity2.ts, 0, 0)) + + A = 1e999, +>A : Symbol(Foo.A, Decl(fakeInfinity2.ts, 0, 17)) + + B = -1e999, +>B : Symbol(Foo.B, Decl(fakeInfinity2.ts, 1, 14)) +} + +namespace X { +>X : Symbol(X, Decl(fakeInfinity2.ts, 3, 1)) + + type A = 1e999; +>A : Symbol(A, Decl(fakeInfinity2.ts, 5, 13)) + + type B = 2e999; +>B : Symbol(B, Decl(fakeInfinity2.ts, 6, 19)) + + export function f(): A { +>f : Symbol(f, Decl(fakeInfinity2.ts, 7, 19)) +>A : Symbol(A, Decl(fakeInfinity2.ts, 5, 13)) + + throw new Error() +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + } +} + +export const m = X.f(); +>m : Symbol(m, Decl(fakeInfinity2.ts, 14, 12)) +>X.f : Symbol(X.f, Decl(fakeInfinity2.ts, 7, 19)) +>X : Symbol(X, Decl(fakeInfinity2.ts, 3, 1)) +>f : Symbol(X.f, Decl(fakeInfinity2.ts, 7, 19)) + diff --git a/tests/baselines/reference/fakeInfinity2.types b/tests/baselines/reference/fakeInfinity2.types new file mode 100644 index 0000000000000..0303d2c1d1ef6 --- /dev/null +++ b/tests/baselines/reference/fakeInfinity2.types @@ -0,0 +1,41 @@ +//// [tests/cases/compiler/fakeInfinity2.ts] //// + +=== fakeInfinity2.ts === +export enum Foo { +>Foo : Foo + + A = 1e999, +>A : Foo.A +>1e999 : Infinity + + B = -1e999, +>B : Foo.B +>-1e999 : -Infinity +>1e999 : Infinity +} + +namespace X { +>X : typeof X + + type A = 1e999; +>A : Infinity + + type B = 2e999; +>B : Infinity + + export function f(): A { +>f : () => Infinity + + throw new Error() +>new Error() : Error +>Error : ErrorConstructor + } +} + +export const m = X.f(); +>m : Infinity +>X.f() : Infinity +>X.f : () => Infinity +>X : typeof X +>f : () => Infinity + diff --git a/tests/baselines/reference/fakeInfinity3.js b/tests/baselines/reference/fakeInfinity3.js new file mode 100644 index 0000000000000..dbde9c2ce72b8 --- /dev/null +++ b/tests/baselines/reference/fakeInfinity3.js @@ -0,0 +1,70 @@ +//// [tests/cases/compiler/fakeInfinity3.ts] //// + +//// [fakeInfinity3.ts] +export enum Foo { + A = 1e999, + B = -1e999, +} + +namespace X { + type A = 1e999; + type B = 2e999; + + export function f(): A { + throw new Error() + } +} + +export const m = X.f(); + +export const Infinity = "oops"; + + +//// [fakeInfinity3.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Infinity = exports.m = exports.Foo = void 0; +var Foo; +(function (Foo) { + Foo[Foo["A"] = Infinity] = "A"; + Foo[Foo["B"] = -Infinity] = "B"; +})(Foo || (exports.Foo = Foo = {})); +var X; +(function (X) { + function f() { + throw new Error(); + } + X.f = f; +})(X || (X = {})); +exports.m = X.f(); +exports.Infinity = "oops"; + + +//// [fakeInfinity3.d.ts] +export declare enum Foo { + A = Infinity, + B = -Infinity +} +export declare const m: Infinity; +export declare const Infinity = "oops"; + + +//// [DtsFileErrors] + + +fakeInfinity3.d.ts(3,9): error TS1066: In ambient enum declarations member initializer must be constant expression. +fakeInfinity3.d.ts(5,25): error TS2749: 'Infinity' refers to a value, but is being used as a type here. Did you mean 'typeof Infinity'? + + +==== fakeInfinity3.d.ts (2 errors) ==== + export declare enum Foo { + A = Infinity, + B = -Infinity + ~~~~~~~~~ +!!! error TS1066: In ambient enum declarations member initializer must be constant expression. + } + export declare const m: Infinity; + ~~~~~~~~ +!!! error TS2749: 'Infinity' refers to a value, but is being used as a type here. Did you mean 'typeof Infinity'? + export declare const Infinity = "oops"; + \ No newline at end of file diff --git a/tests/baselines/reference/fakeInfinity3.symbols b/tests/baselines/reference/fakeInfinity3.symbols new file mode 100644 index 0000000000000..670ef0ee6521c --- /dev/null +++ b/tests/baselines/reference/fakeInfinity3.symbols @@ -0,0 +1,40 @@ +//// [tests/cases/compiler/fakeInfinity3.ts] //// + +=== fakeInfinity3.ts === +export enum Foo { +>Foo : Symbol(Foo, Decl(fakeInfinity3.ts, 0, 0)) + + A = 1e999, +>A : Symbol(Foo.A, Decl(fakeInfinity3.ts, 0, 17)) + + B = -1e999, +>B : Symbol(Foo.B, Decl(fakeInfinity3.ts, 1, 14)) +} + +namespace X { +>X : Symbol(X, Decl(fakeInfinity3.ts, 3, 1)) + + type A = 1e999; +>A : Symbol(A, Decl(fakeInfinity3.ts, 5, 13)) + + type B = 2e999; +>B : Symbol(B, Decl(fakeInfinity3.ts, 6, 19)) + + export function f(): A { +>f : Symbol(f, Decl(fakeInfinity3.ts, 7, 19)) +>A : Symbol(A, Decl(fakeInfinity3.ts, 5, 13)) + + throw new Error() +>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + } +} + +export const m = X.f(); +>m : Symbol(m, Decl(fakeInfinity3.ts, 14, 12)) +>X.f : Symbol(X.f, Decl(fakeInfinity3.ts, 7, 19)) +>X : Symbol(X, Decl(fakeInfinity3.ts, 3, 1)) +>f : Symbol(X.f, Decl(fakeInfinity3.ts, 7, 19)) + +export const Infinity = "oops"; +>Infinity : Symbol(Infinity, Decl(fakeInfinity3.ts, 16, 12)) + diff --git a/tests/baselines/reference/fakeInfinity3.types b/tests/baselines/reference/fakeInfinity3.types new file mode 100644 index 0000000000000..30eb4d11a9a62 --- /dev/null +++ b/tests/baselines/reference/fakeInfinity3.types @@ -0,0 +1,45 @@ +//// [tests/cases/compiler/fakeInfinity3.ts] //// + +=== fakeInfinity3.ts === +export enum Foo { +>Foo : Foo + + A = 1e999, +>A : Foo.A +>1e999 : Infinity + + B = -1e999, +>B : Foo.B +>-1e999 : -Infinity +>1e999 : Infinity +} + +namespace X { +>X : typeof X + + type A = 1e999; +>A : Infinity + + type B = 2e999; +>B : Infinity + + export function f(): A { +>f : () => Infinity + + throw new Error() +>new Error() : Error +>Error : ErrorConstructor + } +} + +export const m = X.f(); +>m : Infinity +>X.f() : Infinity +>X.f : () => Infinity +>X : typeof X +>f : () => Infinity + +export const Infinity = "oops"; +>Infinity : "oops" +>"oops" : "oops" + diff --git a/tests/cases/compiler/fakeInfinity1.ts b/tests/cases/compiler/fakeInfinity1.ts new file mode 100644 index 0000000000000..06fd705a6a248 --- /dev/null +++ b/tests/cases/compiler/fakeInfinity1.ts @@ -0,0 +1,25 @@ +// @strict: true +// @declaration: true + +// These are not actually the real infinity. +export type PositiveInfinity = 1e999; +export type NegativeInfinity = -1e999; + +export type TypeOfInfinity = typeof Infinity; +export type TypeOfNaN = typeof NaN; + +type A = 1e999; +type B = 1e9999; + +declare let a: A; +declare let b: B; + +a = b; +b = a; + +a = Infinity; +a = 1e999; +a = 1e9999; + +export type Oops = 123456789123456789123456789123456789123456789123456789; +export const oops = 123456789123456789123456789123456789123456789123456789; diff --git a/tests/cases/compiler/fakeInfinity2.ts b/tests/cases/compiler/fakeInfinity2.ts new file mode 100644 index 0000000000000..a2666a5be527a --- /dev/null +++ b/tests/cases/compiler/fakeInfinity2.ts @@ -0,0 +1,18 @@ +// @strict: true +// @declaration: true + +export enum Foo { + A = 1e999, + B = -1e999, +} + +namespace X { + type A = 1e999; + type B = 2e999; + + export function f(): A { + throw new Error() + } +} + +export const m = X.f(); diff --git a/tests/cases/compiler/fakeInfinity3.ts b/tests/cases/compiler/fakeInfinity3.ts new file mode 100644 index 0000000000000..536a48e477e0e --- /dev/null +++ b/tests/cases/compiler/fakeInfinity3.ts @@ -0,0 +1,20 @@ +// @strict: true +// @declaration: true + +export enum Foo { + A = 1e999, + B = -1e999, +} + +namespace X { + type A = 1e999; + type B = 2e999; + + export function f(): A { + throw new Error() + } +} + +export const m = X.f(); + +export const Infinity = "oops";