Skip to content

__importStar sometimes inlined when using dynamic imports with --importHelpers #27415

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
dgoldstein0 opened this issue Sep 28, 2018 · 1 comment
Labels
Bug A bug in TypeScript
Milestone

Comments

@dgoldstein0
Copy link

dgoldstein0 commented Sep 28, 2018

TypeScript Version: 3.1.1

Search Terms: __importStar tslib

Code
a.ts:

import('b').then(b => console.log(b));

compile with

tsc a.ts --esModuleInterop --importHelpers

Expected behavior:
some type errors, but emitted code should require("tslib") and use __importStar from there

Actual behavior:
some type errors and generated code looks like this:

var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
    result["default"] = mod;
    return result;
};
Promise.resolve().then(function () { return __importStar(require('b')); }).then(function (b) { return console.log(b); });

btw an example that works correctly:

import('c').then(b => console.log(b));

class Foo {}

export class Bar extends Foo {}

both the extends and the export seem to be necessary

Playground Link: N/A (--esModuleInterop doesn't exist in the playground)

Related Issues: This is basically #21560 but replacing regular imports with dynamic imports

@ghost
Copy link

ghost commented Sep 2, 2022

I'm seeing the same thing. Typescript is emitting several helpers in a source file that has only type imports and a dynamic import. If I combine importHelpers with noEmitHelpers, Typescript actually outputs bad JS because it references __importStar which isn't defined.

Example source:

import type * as yargs from 'yargs';

const commandModule: yargs.CommandModule = {
    builder: {},
    command: 'scan <path>',
    handler: (argv) => {
        const {scan} = await import('../impl/scan');
        await scan(argv);
    }
}

module.exports = commandModule;

Output (importHelpers: true, noEmitHelpers: false):

"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const commandModule = {
    builder:  {},
    command: 'scan <path>',
    describe: 'scan a workspace for licenses',
    handler: async (argv) => {
        const { scan } = await Promise.resolve().then(() => __importStar(require('../impl/scan')));
        await scan(argv);
    },
};
module.exports = commandModule;
//# sourceMappingURL=scan.js.map

Expected output:

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const commandModule = {
    builder:  {},
    command: 'scan <path>',
    describe: 'scan a workspace for licenses',
    handler: async (argv) => {
        const { scan } = await Promise.resolve().then(() => tslib_1.__importStar(require('../impl/scan')));
        await scan(argv);
    },
};
module.exports = commandModule;
//# sourceMappingURL=scan.js.map

If I change import type * as yargs from 'yargs' to import * as yargs from 'yargs' and use values from the module, then it correctly imports the helpers. If I only use types from the module, then it still erases the import an emits the helpers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A bug in TypeScript
Projects
None yet
Development

No branches or pull requests

4 participants