Skip to content
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

Import statement is incorrectly elided when parent JSX element has a JSX rest spread #15806

Closed
lennartjansson opened this issue May 12, 2017 · 1 comment
Labels
Duplicate An existing issue was already created

Comments

@lennartjansson
Copy link

TypeScript Version: 2.3.1 and 2.3.2

Code

Compile the following with tsc a.tsx --jsx react:

import * as React from 'react';
import * as BarComponent from 'bar';
import { parentProps } from 'baz';

export class FooComponent extends React.Component<{}, {}> {
  render() {
    return <div {...parentProps}><BarComponent /></div>;
  }
}

Expected behavior:

In TS 2.3.0, this results in the following correct output:

"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = Object.setPrototypeOf ||
        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __assign = (this && this.__assign) || Object.assign || function(t) {
    for (var s, i = 1, n = arguments.length; i < n; i++) {
        s = arguments[i];
        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
            t[p] = s[p];
    }
    return t;
};
exports.__esModule = true;
var React = require("react");
var BarComponent = require("bar");
var baz_1 = require("baz");
var FooComponent = (function (_super) {
    __extends(FooComponent, _super);
    function FooComponent() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    FooComponent.prototype.render = function () {
        return React.createElement("div", __assign({}, baz_1.parentProps),
            React.createElement(BarComponent, null));
    };
    return FooComponent;
}(React.Component));
exports.FooComponent = FooComponent;

Note that module 'bar' is imported and BarComponent is defined correctly.

Actual behavior:

Compile again with TS 2.3.1 and re-run:

"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = Object.setPrototypeOf ||
        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __assign = (this && this.__assign) || Object.assign || function(t) {
    for (var s, i = 1, n = arguments.length; i < n; i++) {
        s = arguments[i];
        for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
            t[p] = s[p];
    }
    return t;
};
exports.__esModule = true;
var React = require("react");
var baz_1 = require("baz");
var FooComponent = (function (_super) {
    __extends(FooComponent, _super);
    function FooComponent() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    FooComponent.prototype.render = function () {
        return React.createElement("div", __assign({}, baz_1.parentProps),
            React.createElement(BarComponent, null));
    };
    return FooComponent;
}(React.Component));
exports.FooComponent = FooComponent;

Despite BarComponent still being used in the body of the render function, the import statement for the 'bar' module is elided and BarComponent will be undefined. Seems like a serious correctness issue.

The culprit appears to be the JSX rest spread. If the JSX rest spread is removed from the div element, the output is correct:

Input

import * as React from 'react';
import * as BarComponent from 'bar';

export class FooComponent extends React.Component<{}, {}> {
  render() {
    return <div><BarComponent /></div>;
  }
}

Output, TS 2.3.1

"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = Object.setPrototypeOf ||
        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
exports.__esModule = true;
var React = require("react");
var BarComponent = require("bar");
var FooComponent = (function (_super) {
    __extends(FooComponent, _super);
    function FooComponent() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    FooComponent.prototype.render = function () {
        return React.createElement("div", null,
            React.createElement(BarComponent, null));
    };
    return FooComponent;
}(React.Component));
exports.FooComponent = FooComponent;
@mhegazy
Copy link
Contributor

mhegazy commented May 12, 2017

Duplicate of #15469. Should be fixed in TS 2.3.3
(available next week).

the fix should be already intypescript@next give it a try and let us know if you are still running into issues.

@mhegazy mhegazy added the Duplicate An existing issue was already created label May 12, 2017
@yuit yuit closed this as completed May 17, 2017
@microsoft microsoft locked and limited conversation to collaborators Jun 14, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

3 participants