Incorrect import elision when enum value references another enum from a different module
When one enum assigns values from an imported enum, tsgo removes the import but the compiled code still tries to use it, causing a crash at runtime. This works correctly in tsc.
Steps to reproduce
File: system.workorder.status.ts
export enum SystemWorkOrderStatus {
Open = 'Open',
InProgress = 'In Progress',
Completed = 'Completed',
Finalised = 'Finalised',
}
File: bulk.invoice.ts
import { SystemWorkOrderStatus } from './system.workorder.status';
export enum BulkInvoiceJobStatus {
InProgress = SystemWorkOrderStatus.InProgress,
Completed = SystemWorkOrderStatus.Completed,
Finalised = SystemWorkOrderStatus.Finalised,
}
Behavior with [email protected]
Reference to other enum erased and replaced with value.
var BulkInvoiceJobStatus;
(function (BulkInvoiceJobStatus) {
BulkInvoiceJobStatus["InProgress"] = "In Progress";
BulkInvoiceJobStatus["Completed"] = "Completed";
BulkInvoiceJobStatus["Finalised"] = "Finalised";
})(BulkInvoiceJobStatus || (BulkInvoiceJobStatus = {}));
Behavior with tsgo
Reference to original enum maintained without import causes run time error.
var BulkInvoiceJobStatus;
(function (BulkInvoiceJobStatus) {
BulkInvoiceJobStatus["InProgress"] = system_workorder_status_1.SystemWorkOrderStatus.InProgress;
BulkInvoiceJobStatus["Completed"] = system_workorder_status_1.SystemWorkOrderStatus.Completed;
BulkInvoiceJobStatus["Finalised"] = system_workorder_status_1.SystemWorkOrderStatus.Finalised;
})(BulkInvoiceJobStatus || (BulkInvoiceJobStatus = {}));
Runtime error:
ReferenceError: system_workorder_status_1 is not defined
@thaoula, in 5.9, does it emit require, or only the evaluated values?
var BulkInvoiceJobStatus;
(function (BulkInvoiceJobStatus) {
BulkInvoiceJobStatus["InProgress"] = "In Progress";
BulkInvoiceJobStatus["Completed"] = "Completed";
BulkInvoiceJobStatus["Finalised"] = "Finalised";
})(BulkInvoiceJobStatus || (exports.BulkInvoiceJobStatus = BulkInvoiceJobStatus = {}));
Here are is the real files you are write to question about about the emit require .. actually my above was totally messed up your @a-tarasyuk is correct.
TSGO
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BulkInvoiceJobStatus = exports.BulkInvoiceLineValue = exports.BulkInvoiceCommandId = void 0;
var BulkInvoiceCommandId;
(function (BulkInvoiceCommandId) {
BulkInvoiceCommandId["Create"] = "Create";
})(BulkInvoiceCommandId || (exports.BulkInvoiceCommandId = BulkInvoiceCommandId = {}));
var BulkInvoiceLineValue;
(function (BulkInvoiceLineValue) {
BulkInvoiceLineValue["JobType"] = "Job.Type";
BulkInvoiceLineValue["JobDescription"] = "Job.Description";
BulkInvoiceLineValue["JobPrimaryContact"] = "Job.PrimaryContact";
BulkInvoiceLineValue["JobAddressName"] = "Job.Address.Name";
BulkInvoiceLineValue["JobContractors"] = "Job.Contractors";
BulkInvoiceLineValue["JobResources"] = "Job.Resources";
BulkInvoiceLineValue["JobAppointments"] = "Job.Appointments";
})(BulkInvoiceLineValue || (exports.BulkInvoiceLineValue = BulkInvoiceLineValue = {}));
var BulkInvoiceJobStatus;
(function (BulkInvoiceJobStatus) {
BulkInvoiceJobStatus["InProgress"] = job_1.SystemWorkOrderStatus.InProgress;
if (typeof BulkInvoiceJobStatus.InProgress !== "string") BulkInvoiceJobStatus[BulkInvoiceJobStatus.InProgress] = "InProgress";
BulkInvoiceJobStatus["Completed"] = job_1.SystemWorkOrderStatus.Completed;
if (typeof BulkInvoiceJobStatus.Completed !== "string") BulkInvoiceJobStatus[BulkInvoiceJobStatus.Completed] = "Completed";
BulkInvoiceJobStatus["Finalised"] = job_1.SystemWorkOrderStatus.Finalised;
if (typeof BulkInvoiceJobStatus.Finalised !== "string") BulkInvoiceJobStatus[BulkInvoiceJobStatus.Finalised] = "Finalised";
})(BulkInvoiceJobStatus || (exports.BulkInvoiceJobStatus = BulkInvoiceJobStatus = {}));
TSC
Object.defineProperty(exports, "__esModule", { value: true });
exports.BulkInvoiceJobStatus = exports.BulkInvoiceLineValue = exports.BulkInvoiceCommandId = void 0;
var BulkInvoiceCommandId;
(function (BulkInvoiceCommandId) {
BulkInvoiceCommandId["Create"] = "Create";
})(BulkInvoiceCommandId || (exports.BulkInvoiceCommandId = BulkInvoiceCommandId = {}));
var BulkInvoiceLineValue;
(function (BulkInvoiceLineValue) {
BulkInvoiceLineValue["JobType"] = "Job.Type";
BulkInvoiceLineValue["JobDescription"] = "Job.Description";
BulkInvoiceLineValue["JobPrimaryContact"] = "Job.PrimaryContact";
BulkInvoiceLineValue["JobAddressName"] = "Job.Address.Name";
BulkInvoiceLineValue["JobContractors"] = "Job.Contractors";
BulkInvoiceLineValue["JobResources"] = "Job.Resources";
BulkInvoiceLineValue["JobAppointments"] = "Job.Appointments";
})(BulkInvoiceLineValue || (exports.BulkInvoiceLineValue = BulkInvoiceLineValue = {}));
var BulkInvoiceJobStatus;
(function (BulkInvoiceJobStatus) {
BulkInvoiceJobStatus["InProgress"] = "In Progress";
BulkInvoiceJobStatus["Completed"] = "Completed";
BulkInvoiceJobStatus["Finalised"] = "Finalised";
})(BulkInvoiceJobStatus || (exports.BulkInvoiceJobStatus = BulkInvoiceJobStatus = {}));
Runtime error -
BulkInvoiceJobStatus["InProgress"] = job_1.SystemWorkOrderStatus.InProgress;
^
ReferenceError: job_1 is not defined
at /home/app/dist/libs/model/entities/invoicing/bulk.invoice.js:20:42
at Object.<anonymous> (/home/app/dist/libs/model/entities/invoicing/bulk.invoice.js:26:3)
I have updated my original post because my cut down example was actually incorrect
@jakebailey Should the extracted evaluator (https://github.com/microsoft/typescript-go/pull/607) evaluate the expression, or should it preserve the imports in this case? It seems that entity evaluation doesn't currently support alias resolution or import preservation.
https://github.com/microsoft/typescript-go/blob/2ae410164f653c5e2bbb595e38b630c819f7e325/internal/transformers/tstransforms/runtimesyntax.go#L456-L478
https://github.com/microsoft/typescript-go/blob/2ae410164f653c5e2bbb595e38b630c819f7e325/internal/transformers/tstransforms/runtimesyntax.go#L1115-L1139
Enums are in a weird place because early on we thought we could avoid doing const inling, and in general avoid using the checker for them. But we then flipped back to "let's just do it the old way", so I would in general say that we should just be making it work like it used to.