Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

converting typescript async/await generates a lot of javascript code

when I try to compile Typescript async function, it generates a lot of JavaScript code. I tried changing the target flag, the noEmitHelpers in the TSConfig file but gives me always the same thing. is this normal or am I missing something ?

code in Typescript

export async function f(msg: string) {
    
}

generates :

"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (_) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
exports.__esModule = true;
exports.f = void 0;
function f(params) {
    return __awaiter(this, void 0, void 0, function () {
        return __generator(this, function (_a) {
            return [2 /*return*/];
        });
    });
}
exports.f = f;
like image 321
Houcem Eddine Avatar asked Oct 25 '25 04:10

Houcem Eddine


2 Answers

This is governed by the target property is tsconfig.json. And yes it's normal.

In order to emit async/await without transpilation, you need to set the target to ES2017 or later. ES3, ES5, ES2015 and ES2016 all lack native support for async/await, so typescript adds polyfill functions to emulate them.

You can see this on the playground. Click ".js" on the right hand side to see the compiled output. Then click "TS Config" at the top and try different "target" values. See how the compiled JS changes on the right.

TSConfig target on typescript playground

So you can set you project to ES2017 or later, however if your code runs on an older javascript engine without native support for these features, then you code will not work. That's the tradeoff.


Somewhat interestingly, you'll note that if you have a ES2015 or ES2016 target, then it generates less extra code. This is because those versions support generator functions, but still lack async/await support. And generators are used to polyfill async/await support. So because it doesn't need to also polyfill generators, you get less generated code.

like image 64
Alex Wayne Avatar answered Oct 26 '25 16:10

Alex Wayne


TL;DR: Forgetting to use either of the following will cause error output in the terminal and unexpected output to your index.js file from your index.ts file

"target": "esnext" in your tsconfig.json

tsc -p .

For instance, if you targeted a single file like index.js instead of a project directory, you will get error output and unintended index.js output too

tsc -p index.js

Then your project will target the current directory.

If you would like to see a workflow starting with an empty directory

Create a new typescript file

touch index.ts

Put some async typescript code in it to prove the point later

async function hello() {
  return "hi";
}

Install typescript globally (typically avoid global installs but do this here)

npm i -g typescript

Create a new package.json

npm init -y

Create a new tsconfig.json

tsc --init

Edit that file to be able to compile to human readable javascript

{
  "compilerOptions": {
    "target": "esnext" /** latest js/es6, required for human readable js */,
   }
}

That is the only config you require for human readable js

Run tsc compile command on all your files that are in your current directory

tsc -p .

View your recently created index.js file

cat index.js

It will be human readable now.

Then feel free to create a package.json file

npm init -y

And store what you want in the scripts section to make it automated easily

"scripts": {
    "dev": "yarn compile; yarn show; yarn start;",
    "compile": "tsc -p .",
    "show": "bat index.js",
    "start": "node index.js",
}

Then run any of the following

yarn dev # will run compile, show then start

yarn compile # yarn show # similar to cat, bat just shows a file yarn start # run your newly created index.js file with node to verify it works without errors

like image 40
jasonleonhard Avatar answered Oct 26 '25 16:10

jasonleonhard



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!