4

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;
4
  • 1
    Can you share your typescript/babel config? Try to reproduce it in typescriptlang.org Commented Nov 5, 2021 at 16:48
  • On Codepen, when I paste your Typescript line, the compiled Javascript is export async function f(msg) { } and that's it. Is this file part of a module? Are there other files around or something? It's not alone, is it? Commented Nov 5, 2021 at 16:53
  • it is alone in a folder with tsconfig file Commented Nov 5, 2021 at 19:05
  • I have a folder witch contain t.ts file, typescript is installed globally, when I run the command ` tsc t.ts` it generates a file t.js with a lot of code, but when I run only tsc it generates JavaScript normally Commented Nov 5, 2021 at 23:32

2 Answers 2

6

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.

Sign up to request clarification or add additional context in comments.

2 Comments

I have a folder witch contain t.ts file, typescript is installed globally, when I run the command ` tsc t.ts` it generates a file t.js with a lot of code, but when I run only tsc it generates JavaScript normally
You probably need to provide a --project option that is a path your tsconfig. See: typescriptlang.org/docs/handbook/compiler-options.html
1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.