Employing various Class Methods based on the chosen target compiler option

Is there a way to instruct TypeScript to utilize different implementations of methods within the same class, based on the specified target option in the tsconfig.json file?

I am currently transitioning one of my scripts to TypeScript to streamline management of codebases by consolidating an ES5 and an ES6 file into a single source. Due to TypeScript's ability to switch output targets in the tsconfig.json file, I aim to have a single version that can be easily updated and maintained.

The challenge arises from using a generator in the ES6 version, which should not pose a problem as TypeScript automatically adds a pseudo-generator to the top of the ES5 output. However, my current Pseudo-Generator implementation in the ES5 file is more concise and clean.

Possible Solutions

Is there a method to override the respective "generator" method or use specialized comment annotations (such as //@ts-target) to specify which code (function body) to use based on the selected target in the configuration file, even if it is not documented officially?

Integrating an additional function or script into the TypeScript compiler process may provide assistance since I compile both ES files through a small node.js script without directly altering the tsconfig.json file.

Alternatively, is there an extension available to segregate different methods of a class into separate files? This would enable extraction of the respective "generator" methods. However, this approach raises questions regarding linking them based on the target, given that I utilize /// <reference /> linking in the main script file for consolidation.

Any innovative suggestions?

class Option {
    ///@ts-target ES5
    __walkerVariable1:any undefined
    __walkerVariable2:any undefined
    __walkerVariable3:any undefined
    walker() {
        /* Pseudo-Walker Code for ES5 */
    }

    ///@ts-target ES6
    *walker() {
        /* Real Walker Code for ES6 */
    }
}

Currently, a Pseudo-Generator code is injected into the ES5 version of my script. I aspire to address this challenge by implementing a different method/function that houses my personal Pseudo-Generator. Therefore, I seek guidance on how to instruct TypeScript to disregard the Pseudo-Generator in ES6/Real-Generator in ES5 and only include one of them based on the chosen target option.

Answer №1

After some careful consideration, I managed to tackle a tricky problem by seeking guidance from an informative GitHub issue.

In my approach, I utilize a custom node.js script to compile TypeScript files into two distinct JavaScript versions, ES5 and ES6. This involves leveraging the TypeScript API and utilizing the ts.createProgram method, which allows for the integration of a host object as a third parameter. The host object facilitates various compiler processes, including the file loader method known as getSourceFile.

The remainder of the process is relatively straightforward: I employ regular expressions to identify and filter custom comment annotations such as \\\@ts-target:ES5 and \\\@ts-target:ES6. While it may not be the most elegant solution, it effectively achieves the desired outcome!

function compileTS(){
    let config = readConfig("ts/tsconfig.json");
    let host = ts.createCompilerHost(config.options);
    let sourceFile = host.getSourceFile;

    // Generating ES5 JavaScript
    (function(config){
        host.getSourceFile = function(filename) {
            if(filename === "ts/options.ts"){
                let file = fs.readFileSync("./ts/options.ts").toString();
                file = file.replace(/[ ]+\/\/\/\@ts\-target\:ES6\s+([\s\S]*)\/\/\/\@ts\-target\:ES6/gm, "");
                return ts.createSourceFile(filename, file, ts.ScriptTarget.ES5, true);
            }
            return sourceFile.call(host, filename);
        }
        let program = ts.createProgram(config.fileNames, config.options, host);
        let emitResult = program.emit();
        report(ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics));
        if(emitResult.emitSkipped){
            process.exit(1);
        }
    }(config));

    // Generating ES6 JavaScript
    config.options.target = 2;
    config.options.outFile = "../dist/js/tail.select-es6.js";
    (function(config){
        host.getSourceFile = function(filename) {
            if(filename === "ts/options.ts"){
                let file = fs.readFileSync("./ts/options.ts").toString();
                file = file.replace(/[ ]+\/\/\/\@ts\-target\:ES5\s+([\s\S]*)\/\/\/\@ts\-target\:ES5/gm, "");
                return ts.createSourceFile(filename, file, ts.ScriptTarget.ES2015, true);
            }
            return sourceFile.call(host, filename);
        }
        let program = ts.createProgram(config.fileNames, config.options, host);
        let emitResult = program.emit();
        report(ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics));
        if(emitResult.emitSkipped){
            process.exit(1);
        }
    }(config));
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Dynamically showing a div using JavaScript and AJAX after changing the window location

After successfully fetching data from the server through AJAX, I am redirecting to the same screen/URL. Is it possible to show/display a div after redirecting using jQuery? $.ajax({ type: "POST", url: action, data: form_data, success: func ...

"Make sure to tick the checkbox if it's not already selected,

Could use some assistance with traversing and logic in this scenario. Here is the logic breakdown: If any checkbox in column3 is checked, then check the first column checkbox. If none in column 3 are selected, uncheck checkbox in column1. If column1 ...

When submitting an Asp net mvc Form, some fields may not be posted as expected

I'm facing an issue with my ASP.NET MVC application form. Some fields that should be posted are missing, and I can't figure out why. <form id="FormRegistroUsuario" action="/Account/AdminSecurityUserAccountAdd"> <fieldset> ...

Issue with form action redirection on Node JS Express server not functioning correctly

My EJS application involves using jQuery in the JavaScript code to fetch JSON data from the Google Custom Search API. The app then uses the GET method to navigate to /search, passing the query as the attribute for q. Here's an example of the form&apos ...

Storing a JSON as a cookie in a Django response

Is there a way to store a dictionary/json object in a client-side cookie from Django and retrieve it as a JavaScript object? response = HttpResponseRedirect(reverse('app:home')) response.set_cookie('cookiekey', 'value') retu ...

jQuery DatePicker Not Displaying Calendar

I've been attempting to implement a date picker in jQuery. I've included the necessary code within the head tag: <link rel="stylesheet" type="text/css" media="screen" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jqu ...

How can I pass an array object from an HTML form that adheres to a Mongoose schema

I have this HTML form that I'm using to create a new document in my mongo database. The document represents notes given to a teacher based on various criteria. I am storing the notes in an array within the note property, each object containing the aut ...

Guide on including a in-browser utility module from single-spa into a TypeScript parcel project

There are 3 TypeScript projects listed below: root-config a parcel project named my-app an in-browser utility module called api All of these projects were created using the create-single-spa command. In the file api/src/lomse-api.ts, I am exporting the ...

Troubleshooting issue with Highcharts 3D rendering after using setState()

When working on implementing a 3d pie chart in React using react highchart, I encountered an issue. Whenever I utilize this.setState() inside the lifecycle method componentDidMount(), the 3d chart shifts from its original position to the right diagonally. ...

How can one click the button within the expanded dropdown while hovering over the navigation item in Angular and Bootstrap?

Issue Description: Upon hovering over a navigation item, the dropdown container is displayed but it's not clickable. Desired Behavior: Hovering over a navigation item should display the dropdown container and allow clicking on its contents. Furthermo ...

Color picker can be utilized as an HTML input element by following these steps

After trying out various color pickers, I was not satisfied with their performance until I stumbled upon Spectrum - The No Hassle jQuery Colorpicker. It perfectly met my requirements. <html> <head> <meta http-equiv="content-type" content="t ...

There has been an issue with parsing the JSON file due to an invalid character found at

I keep encountering a parse error whenever I attempt to send a post request to the server. $.post("../php/user_handler.php", formData, function(data) { var result = JSON.parse(data); if(result.status === 'error') { ...

Calculating the average value of an attribute in an array using Mongodb (Mongoose)

Seeking assistance with a query to find sellers near users based on location input and sorting them by average rating. Is this achievable? Snippet of the model including an array of reviews: const sellerSchema = new mongoose.Schema({ _id: Mongo ...

Error in Angular 2: Component unable to locate imported module

I'm facing an issue where a module I want to use in my application cannot be found. The error message I receive is: GET http://product-admin.dev/node_modules/angular2-toaster/ 404 (Not Found) The module was installed via NPM and its Github reposito ...

React not displaying wrapped div

I am facing an issue with my render() function where the outer div is not rendering, but the inner ReactComponent is displaying. Here is a snippet of my code: return( <div style={{background: "black"}}> <[ReactComponent]> ...

Identify the mouse's location in relation to its parent element, not the entire webpage

A script I've been working on detects the mouse position relative to the page, taking into account a movement threshold of 100px before triggering certain actions. // Keep track of last cursor positions var cursorDistance = 0; var lastCursorX = null; ...

Troubleshooting React/Jest issues with updating values in Select elements on onChange event

I am currently testing the Select element's value after it has been changed with the following code: it("changes value after selecting another field", () => { doSetupWork(); let field = screen.getByLabelText("MySelectField") ...

Is it possible to launch a React application with a specific Redux state preloaded?

Is there a way to skip navigating through a bulky frontend application in order to reach the specific component I want to modify? I'm curious if it's feasible to save the redux store and refresh my application after every code alteration using t ...

Can Angular components be used to replace a segment of a string?

Looking to integrate a tag system in Angular similar to Instagram or Twitter. Unsure of the correct approach for this task. Consider a string like: Hello #xyz how are you doing?. I aim to replace #xyz with <tag-component [input]="xyz">&l ...

Save the retrieved data in a variable and pass the entire JSON object as a prop to a React component

Having some trouble with my code. I need the app to fetch a JSON from an API and pass it as a prop so that each component file can use it and display the element on the screen. The issue is, I can't seem to figure out how to store the fetched informa ...